提交 512bd8b8 编写于 作者: Y yhuang

Merge

......@@ -194,3 +194,4 @@ a8012d8d7e9c5035de0bdd4887dc9f7c54008f21 jdk8-b69
a996b57e554198f4592a5f3c30f2f9f4075e545d jdk8-b70
2a5af0f766d0acd68a81fb08fe11fd66795f86af jdk8-b71
32a57e645e012a1f0665c075969ca598e0dbb948 jdk8-b72
733885f57e14cc27f5a5ff0dffe641d2fa3c704a jdk8-b73
......@@ -375,6 +375,7 @@ TOOLS = \
com/sun/tools/javadoc \
com/sun/tools/javah \
com/sun/tools/javap \
com/sun/tools/jdeps \
com/sun/tools/corba \
com/sun/tools/internal/xjc \
com/sun/tools/internal/ws \
......@@ -457,6 +458,7 @@ NOTJRETOOLS = \
javadoc$(EXE_SUFFIX) \
javah$(EXE_SUFFIX) \
javap$(EXE_SUFFIX) \
jdeps$(EXE_SUFFIX) \
jcmd$(EXE_SUFFIX) \
jdb$(EXE_SUFFIX) \
jps$(EXE_SUFFIX) \
......@@ -564,6 +566,7 @@ $(NOT_RT_JAR_LIST): FRC
$(ECHO) "sun/tools/javac/" >> $@
$(ECHO) "com/sun/tools/classfile/" >> $@
$(ECHO) "com/sun/tools/javap/" >> $@
$(ECHO) "com/sun/tools/jdeps/" >> $@
$(ECHO) "sun/tools/jcmd/" >> $@
$(ECHO) "sun/tools/jconsole/" >> $@
$(ECHO) "sun/tools/jps/" >> $@
......
......@@ -76,7 +76,7 @@ ATTACH_PKGS = com.sun.tools.attach \
JCONSOLE_PKGS = com.sun.tools.jconsole
TREEAPI_PKGS = com.sunsource.doctree \
TREEAPI_PKGS = com.sun.source.doctree \
com.sun.source.tree \
com.sun.source.util
......
......@@ -63,6 +63,7 @@ $(call make-launcher, javac, com.sun.tools.javac.Main, , )
$(call make-launcher, javadoc, com.sun.tools.javadoc.Main, , )
$(call make-launcher, javah, com.sun.tools.javah.Main, , )
$(call make-launcher, javap, com.sun.tools.javap.Main, , )
$(call make-launcher, jdeps, com.sun.tools.jdeps.Main, , )
$(call make-launcher, jcmd, sun.tools.jcmd.JCmd, , )
$(call make-launcher, jconsole, sun.tools.jconsole.JConsole, \
-J-Djconsole.showOutputViewer, )
......
......@@ -62,6 +62,10 @@ ifeq ($(PROGRAM),javap)
WILDCARDS=true
NEVER_ACT_AS_SERVER_CLASS_MACHINE=true
endif
ifeq ($(PROGRAM),jdeps)
WILDCARDS=true
NEVER_ACT_AS_SERVER_CLASS_MACHINE=true
endif
ifeq ($(PROGRAM),javah)
WILDCARDS=true
NEVER_ACT_AS_SERVER_CLASS_MACHINE=true
......
......@@ -270,6 +270,11 @@ $(eval $(call SetupLauncher,javap,\
-DNEVER_ACT_AS_SERVER_CLASS_MACHINE \
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.javap.Main"$(COMMA) }'))
$(eval $(call SetupLauncher,jdeps,\
-DEXPAND_CLASSPATH_WILDCARDS \
-DNEVER_ACT_AS_SERVER_CLASS_MACHINE \
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.jdeps.Main"$(COMMA) }'))
BUILD_LAUNCHER_jconsole_CFLAGS_windows:=-DJAVAW
BUILD_LAUNCHER_jconsole_LDFLAGS_windows:=user32.lib
......
......@@ -747,6 +747,7 @@ TOOLS_JAR_INCLUDES := \
com/sun/tools/javadoc \
com/sun/tools/javah \
com/sun/tools/javap \
com/sun/tools/jdeps \
com/sun/tools/jdi \
com/sun/tools/script/shell \
com/sun/xml/internal/dtdparser \
......
......@@ -103,6 +103,7 @@ NOT_JRE_BIN_FILES := \
javadoc$(EXE_SUFFIX) \
javah$(EXE_SUFFIX) \
javap$(EXE_SUFFIX) \
jdeps$(EXE_SUFFIX) \
jcmd$(EXE_SUFFIX) \
jdb$(EXE_SUFFIX) \
jps$(EXE_SUFFIX) \
......
/*
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -30,6 +30,7 @@ import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import javax.crypto.BadPaddingException;
import java.nio.ByteBuffer;
/**
* This class implements the AES algorithm in its various modes
......@@ -127,6 +128,21 @@ abstract class AESCipher extends CipherSpi {
super(32, "CFB", "NOPADDING");
}
}
public static final class AES128_GCM_NoPadding extends OidImpl {
public AES128_GCM_NoPadding() {
super(16, "GCM", "NOPADDING");
}
}
public static final class AES192_GCM_NoPadding extends OidImpl {
public AES192_GCM_NoPadding() {
super(24, "GCM", "NOPADDING");
}
}
public static final class AES256_GCM_NoPadding extends OidImpl {
public AES256_GCM_NoPadding() {
super(32, "GCM", "NOPADDING");
}
}
// utility method used by AESCipher and AESWrapCipher
static final void checkKeySize(Key key, int fixedKeySize)
......@@ -531,4 +547,79 @@ abstract class AESCipher extends CipherSpi {
return core.unwrap(wrappedKey, wrappedKeyAlgorithm,
wrappedKeyType);
}
/**
* Continues a multi-part update of the Additional Authentication
* Data (AAD), using a subset of the provided buffer.
* <p>
* Calls to this method provide AAD to the cipher when operating in
* modes such as AEAD (GCM/CCM). If this cipher is operating in
* either GCM or CCM mode, all AAD must be supplied before beginning
* operations on the ciphertext (via the {@code update} and {@code
* doFinal} methods).
*
* @param src the buffer containing the AAD
* @param offset the offset in {@code src} where the AAD input starts
* @param len the number of AAD bytes
*
* @throws IllegalStateException if this cipher is in a wrong state
* (e.g., has not been initialized), does not accept AAD, or if
* operating in either GCM or CCM mode and one of the {@code update}
* methods has already been called for the active
* encryption/decryption operation
* @throws UnsupportedOperationException if this method
* has not been overridden by an implementation
*
* @since 1.8
*/
@Override
protected void engineUpdateAAD(byte[] src, int offset, int len) {
core.updateAAD(src, offset, len);
}
/**
* Continues a multi-part update of the Additional Authentication
* Data (AAD).
* <p>
* Calls to this method provide AAD to the cipher when operating in
* modes such as AEAD (GCM/CCM). If this cipher is operating in
* either GCM or CCM mode, all AAD must be supplied before beginning
* operations on the ciphertext (via the {@code update} and {@code
* doFinal} methods).
* <p>
* All {@code src.remaining()} bytes starting at
* {@code src.position()} are processed.
* Upon return, the input buffer's position will be equal
* to its limit; its limit will not have changed.
*
* @param src the buffer containing the AAD
*
* @throws IllegalStateException if this cipher is in a wrong state
* (e.g., has not been initialized), does not accept AAD, or if
* operating in either GCM or CCM mode and one of the {@code update}
* methods has already been called for the active
* encryption/decryption operation
* @throws UnsupportedOperationException if this method
* has not been overridden by an implementation
*
* @since 1.8
*/
@Override
protected void engineUpdateAAD(ByteBuffer src) {
if (src != null) {
int aadLen = src.limit() - src.position();
if (aadLen != 0) {
if (src.hasArray()) {
int aadOfs = src.arrayOffset() + src.position();
core.updateAAD(src.array(), aadOfs, aadLen);
src.position(src.limit());
} else {
byte[] aad = new byte[aadLen];
src.get(aad);
core.updateAAD(aad, 0, aadLen);
}
}
}
}
}
/*
* Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -106,7 +106,7 @@ public final class AESKeyGenerator extends KeyGeneratorSpi {
SecretKeySpec aesKey = null;
if (this.random == null) {
this.random = SunJCE.RANDOM;
this.random = SunJCE.getRandom();
}
byte[] keyBytes = new byte[keySize];
......
/*
* Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -104,7 +104,7 @@ public final class BlowfishKeyGenerator extends KeyGeneratorSpi {
*/
protected SecretKey engineGenerateKey() {
if (this.random == null) {
this.random = SunJCE.RANDOM;
this.random = SunJCE.getRandom();
}
byte[] keyBytes = new byte[this.keysize];
......
/*
* Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -83,9 +83,10 @@ final class CipherTextStealing extends CipherBlockChaining {
* @param plainLen the length of the input data
* @param cipher the buffer for the result
* @param cipherOffset the offset in <code>cipher</code>
* @return the number of bytes placed into <code>cipher</code>
*/
void encryptFinal(byte[] plain, int plainOffset, int plainLen,
byte[] cipher, int cipherOffset)
int encryptFinal(byte[] plain, int plainOffset, int plainLen,
byte[] cipher, int cipherOffset)
throws IllegalBlockSizeException {
if (plainLen < blockSize) {
......@@ -134,6 +135,7 @@ final class CipherTextStealing extends CipherBlockChaining {
embeddedCipher.encryptBlock(tmp2, 0, cipher, cipherOffset);
}
}
return plainLen;
}
/**
......@@ -158,9 +160,10 @@ final class CipherTextStealing extends CipherBlockChaining {
* @param cipherLen the length of the input data
* @param plain the buffer for the result
* @param plainOffset the offset in <code>plain</code>
* @return the number of bytes placed into <code>plain</code>
*/
void decryptFinal(byte[] cipher, int cipherOffset, int cipherLen,
byte[] plain, int plainOffset)
int decryptFinal(byte[] cipher, int cipherOffset, int cipherLen,
byte[] plain, int plainOffset)
throws IllegalBlockSizeException {
if (cipherLen < blockSize) {
throw new IllegalBlockSizeException("input is too short!");
......@@ -211,5 +214,6 @@ final class CipherTextStealing extends CipherBlockChaining {
}
}
}
return cipherLen;
}
}
/*
* Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -102,7 +102,7 @@ public final class DESKeyGenerator extends KeyGeneratorSpi {
DESKey desKey = null;
if (this.random == null) {
this.random = SunJCE.RANDOM;
this.random = SunJCE.getRandom();
}
try {
......
/*
* Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -105,7 +105,7 @@ public final class DESedeKeyGenerator extends KeyGeneratorSpi {
*/
protected SecretKey engineGenerateKey() {
if (this.random == null) {
this.random = SunJCE.RANDOM;
this.random = SunJCE.getRandom();
}
byte[] rawkey = new byte[DESedeKeySpec.DES_EDE_KEY_LEN];
......
/*
* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -217,7 +217,7 @@ public final class DESedeWrapCipher extends CipherSpi {
if (params == null) {
iv = new byte[8];
if (random == null) {
random = SunJCE.RANDOM;
random = SunJCE.getRandom();
}
random.nextBytes(iv);
}
......
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -140,7 +140,7 @@ public final class DHKeyPairGenerator extends KeyPairGeneratorSpi {
*/
public KeyPair generateKeyPair() {
if (random == null) {
random = SunJCE.RANDOM;
random = SunJCE.getRandom();
}
if (params == null) {
......
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -131,7 +131,7 @@ extends AlgorithmParameterGeneratorSpi {
}
if (this.random == null)
this.random = SunJCE.RANDOM;
this.random = SunJCE.getRandom();
try {
AlgorithmParameterGenerator paramGen;
......
/*
* Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -26,7 +26,7 @@
package com.sun.crypto.provider;
import java.security.InvalidKeyException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.*;
/**
* This class represents a block cipher in one of its modes. It wraps
......@@ -150,11 +150,13 @@ abstract class FeedbackCipher {
* @param plainLen the length of the input data
* @param cipher the buffer for the encryption result
* @param cipherOffset the offset in <code>cipher</code>
* @return the number of bytes placed into <code>cipher</code>
*/
void encryptFinal(byte[] plain, int plainOffset, int plainLen,
byte[] cipher, int cipherOffset)
int encryptFinal(byte[] plain, int plainOffset, int plainLen,
byte[] cipher, int cipherOffset)
throws IllegalBlockSizeException {
encrypt(plain, plainOffset, plainLen, cipher, cipherOffset);
return plainLen;
}
/**
* Performs decryption operation.
......@@ -190,10 +192,40 @@ abstract class FeedbackCipher {
* @param cipherLen the length of the input data
* @param plain the buffer for the decryption result
* @param plainOffset the offset in <code>plain</code>
* @return the number of bytes placed into <code>plain</code>
*/
void decryptFinal(byte[] cipher, int cipherOffset, int cipherLen,
byte[] plain, int plainOffset)
throws IllegalBlockSizeException {
int decryptFinal(byte[] cipher, int cipherOffset, int cipherLen,
byte[] plain, int plainOffset)
throws IllegalBlockSizeException, AEADBadTagException {
decrypt(cipher, cipherOffset, cipherLen, plain, plainOffset);
return cipherLen;
}
/**
* Continues a multi-part update of the Additional Authentication
* Data (AAD), using a subset of the provided buffer. If this
* cipher is operating in either GCM or CCM mode, all AAD must be
* supplied before beginning operations on the ciphertext (via the
* {@code update} and {@code doFinal} methods).
* <p>
* NOTE: Given most modes do not accept AAD, default impl for this
* method throws IllegalStateException.
*
* @param src the buffer containing the AAD
* @param offset the offset in {@code src} where the AAD input starts
* @param len the number of AAD bytes
*
* @throws IllegalStateException if this cipher is in a wrong state
* (e.g., has not been initialized), does not accept AAD, or if
* operating in either GCM or CCM mode and one of the {@code update}
* methods has already been called for the active
* encryption/decryption operation
* @throws UnsupportedOperationException if this method
* has not been overridden by an implementation
*
* @since 1.8
*/
void updateAAD(byte[] src, int offset, int len) {
throw new IllegalStateException("No AAD accepted");
}
}
/*
* 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -98,7 +98,7 @@ public final class HmacMD5KeyGenerator extends KeyGeneratorSpi {
*/
protected SecretKey engineGenerateKey() {
if (this.random == null) {
this.random = SunJCE.RANDOM;
this.random = SunJCE.getRandom();
}
byte[] keyBytes = new byte[this.keysize];
......
/*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -89,7 +89,7 @@ public final class HmacPKCS12PBESHA1 extends HmacCore {
// generate default for salt and iteration count if necessary
if (salt == null) {
salt = new byte[20];
SunJCE.RANDOM.nextBytes(salt);
SunJCE.getRandom().nextBytes(salt);
}
if (iCount == 0) iCount = 100;
} else if (!(params instanceof PBEParameterSpec)) {
......
/*
* Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -98,7 +98,7 @@ public final class HmacSHA1KeyGenerator extends KeyGeneratorSpi {
*/
protected SecretKey engineGenerateKey() {
if (this.random == null) {
this.random = SunJCE.RANDOM;
this.random = SunJCE.getRandom();
}
byte[] keyBytes = new byte[this.keysize];
......
/*
* Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -69,7 +69,7 @@ final class ISO10126Padding implements Padding {
byte paddingOctet = (byte) (len & 0xff);
byte[] padding = new byte[len];
SunJCE.RANDOM.nextBytes(padding);
SunJCE.getRandom().nextBytes(padding);
padding[len-1] = paddingOctet;
System.arraycopy(padding, 0, in, off, len);
return;
......
/*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -98,7 +98,7 @@ final class KeyGeneratorCore {
// generate the key
SecretKey implGenerateKey() {
if (random == null) {
random = SunJCE.RANDOM;
random = SunJCE.getRandom();
}
byte[] b = new byte[(keySize + 7) >> 3];
random.nextBytes(b);
......
/*
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -99,7 +99,7 @@ final class KeyProtector {
{
// create a random salt (8 bytes)
byte[] salt = new byte[8];
SunJCE.RANDOM.nextBytes(salt);
SunJCE.getRandom().nextBytes(salt);
// create PBE parameters from salt and iteration count
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, 20);
......@@ -284,7 +284,7 @@ final class KeyProtector {
{
// create a random salt (8 bytes)
byte[] salt = new byte[8];
SunJCE.RANDOM.nextBytes(salt);
SunJCE.getRandom().nextBytes(salt);
// create PBE parameters from salt and iteration count
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, 20);
......
/*
* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -164,7 +164,7 @@ final class PBECipherCore {
AlgorithmParameters params = null;
if (salt == null) {
salt = new byte[8];
SunJCE.RANDOM.nextBytes(salt);
SunJCE.getRandom().nextBytes(salt);
}
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, iCount);
try {
......
/*
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -164,7 +164,7 @@ final class PBES1Core {
AlgorithmParameters params = null;
if (salt == null) {
salt = new byte[8];
SunJCE.RANDOM.nextBytes(salt);
SunJCE.getRandom().nextBytes(salt);
}
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, iCount);
try {
......
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -134,13 +134,13 @@ abstract class PBES2Core extends CipherSpi {
if (salt == null) {
// generate random salt and use default iteration count
salt = new byte[DEFAULT_SALT_LENGTH];
SunJCE.RANDOM.nextBytes(salt);
SunJCE.getRandom().nextBytes(salt);
iCount = DEFAULT_COUNT;
}
if (ivSpec == null) {
// generate random IV
byte[] ivBytes = new byte[blkSize];
SunJCE.RANDOM.nextBytes(ivBytes);
SunJCE.getRandom().nextBytes(ivBytes);
ivSpec = new IvParameterSpec(ivBytes);
}
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, iCount, ivSpec);
......
/*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -123,7 +123,7 @@ abstract class PBMAC1Core extends HmacCore {
// generate default for salt and iteration count if necessary
if (salt == null) {
salt = new byte[DEFAULT_SALT_LENGTH];
SunJCE.RANDOM.nextBytes(salt);
SunJCE.getRandom().nextBytes(salt);
}
if (iCount == 0) iCount = DEFAULT_COUNT;
} else if (!(params instanceof PBEParameterSpec)) {
......
/*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -227,7 +227,7 @@ final class PKCS12PBECipherCore {
// follow the recommendation in PKCS12 v1.0
// section B.4 to generate salt and iCount.
salt = new byte[DEFAULT_SALT_LENGTH];
SunJCE.RANDOM.nextBytes(salt);
SunJCE.getRandom().nextBytes(salt);
iCount = DEFAULT_COUNT;
}
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, iCount);
......@@ -294,7 +294,7 @@ final class PKCS12PBECipherCore {
if (random != null) {
random.nextBytes(salt);
} else {
SunJCE.RANDOM.nextBytes(salt);
SunJCE.getRandom().nextBytes(salt);
}
}
if (iCount == 0) iCount = DEFAULT_COUNT;
......
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -57,6 +57,7 @@ import java.security.SecureRandom;
* - ARCFOUR (RC4 compatible)
*
* - Cipher modes ECB, CBC, CFB, OFB, PCBC, CTR, and CTS for all block ciphers
* and mode GCM for AES cipher
*
* - Cipher padding ISO10126Padding for non-PKCS#5 block ciphers and
* NoPadding and PKCS5Padding for all block ciphers
......@@ -90,7 +91,12 @@ public final class SunJCE extends Provider {
/* Are we debugging? -- for developers */
static final boolean debug = false;
static final SecureRandom RANDOM = new SecureRandom();
// lazy initialize SecureRandom to avoid potential recursion if Sun
// provider has not been installed yet
private static class SecureRandomHolder {
static final SecureRandom RANDOM = new SecureRandom();
}
static SecureRandom getRandom() { return SecureRandomHolder.RANDOM; }
public SunJCE() {
/* We are the "SunJCE" provider */
......@@ -100,7 +106,7 @@ public final class SunJCE extends Provider {
"|CFB8|CFB16|CFB24|CFB32|CFB40|CFB48|CFB56|CFB64" +
"|OFB8|OFB16|OFB24|OFB32|OFB40|OFB48|OFB56|OFB64";
final String BLOCK_MODES128 = BLOCK_MODES +
"|CFB72|CFB80|CFB88|CFB96|CFB104|CFB112|CFB120|CFB128" +
"|GCM|CFB72|CFB80|CFB88|CFB96|CFB104|CFB112|CFB120|CFB128" +
"|OFB72|OFB80|OFB88|OFB96|OFB104|OFB112|OFB120|OFB128";
final String BLOCK_PADS = "NOPADDING|PKCS5PADDING|ISO10126PADDING";
......@@ -258,6 +264,9 @@ public final class SunJCE extends Provider {
put("Cipher.AES_128/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_CFB_NoPadding");
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.4", "AES_128/CFB/NoPadding");
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.4", "AES_128/CFB/NoPadding");
put("Cipher.AES_128/GCM/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_GCM_NoPadding");
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.6", "AES_128/GCM/NoPadding");
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.6", "AES_128/GCM/NoPadding");
put("Cipher.AES_192/ECB/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_ECB_NoPadding");
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.21", "AES_192/ECB/NoPadding");
......@@ -271,7 +280,9 @@ public final class SunJCE extends Provider {
put("Cipher.AES_192/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_CFB_NoPadding");
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.24", "AES_192/CFB/NoPadding");
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.24", "AES_192/CFB/NoPadding");
put("Cipher.AES_192/GCM/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_GCM_NoPadding");
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.26", "AES_192/GCM/NoPadding");
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.26", "AES_192/GCM/NoPadding");
put("Cipher.AES_256/ECB/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_ECB_NoPadding");
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.41", "AES_256/ECB/NoPadding");
......@@ -285,6 +296,9 @@ public final class SunJCE extends Provider {
put("Cipher.AES_256/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_CFB_NoPadding");
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.44", "AES_256/CFB/NoPadding");
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.44", "AES_256/CFB/NoPadding");
put("Cipher.AES_256/GCM/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_GCM_NoPadding");
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.46", "AES_256/GCM/NoPadding");
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.46", "AES_256/GCM/NoPadding");
put("Cipher.AESWrap", "com.sun.crypto.provider.AESWrapCipher$General");
put("Cipher.AESWrap SupportedModes", "ECB");
......@@ -509,6 +523,8 @@ public final class SunJCE extends Provider {
put("AlgorithmParameters.AES",
"com.sun.crypto.provider.AESParameters");
put("Alg.Alias.AlgorithmParameters.Rijndael", "AES");
put("AlgorithmParameters.GCM",
"com.sun.crypto.provider.GCMParameters");
put("AlgorithmParameters.RC2",
......
......@@ -860,9 +860,9 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* @return the specified subsequence.
*
* @throws IndexOutOfBoundsException
* if <tt>start</tt> or <tt>end</tt> are negative,
* if <tt>end</tt> is greater than <tt>length()</tt>,
* or if <tt>start</tt> is greater than <tt>end</tt>
* if {@code start} or {@code end} are negative,
* if {@code end} is greater than {@code length()},
* or if {@code start} is greater than {@code end}
* @spec JSR-51
*/
@Override
......@@ -1292,7 +1292,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
/**
* Returns the index within this string of the first occurrence of the
* specified substring, starting at the specified index. The integer
* returned is the smallest value <tt>k</tt> for which:
* returned is the smallest value {@code k} for which:
* <blockquote><pre>
* k >= Math.min(fromIndex, str.length()) &&
* this.toString().startsWith(str, k)
......@@ -1418,7 +1418,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
public abstract String toString();
/**
* Needed by <tt>String</tt> for the contentEquals method.
* Needed by {@code String} for the contentEquals method.
*/
final char[] getValue() {
return value;
......
/*
* 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 {}
......@@ -773,7 +773,7 @@ public final class Integer extends Number implements Comparable<Integer> {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low));
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
}
high = h;
......
......@@ -615,10 +615,10 @@ public final class String
}
/**
* Returns <tt>true</tt> if, and only if, {@link #length()} is <tt>0</tt>.
* Returns {@code true} if, and only if, {@link #length()} is {@code 0}.
*
* @return <tt>true</tt> if {@link #length()} is <tt>0</tt>, otherwise
* <tt>false</tt>
* @return {@code true} if {@link #length()} is {@code 0}, otherwise
* {@code false}
*
* @since 1.6
*/
......@@ -1229,23 +1229,23 @@ public final class String
/**
* Tests if two string regions are equal.
* <p>
* A substring of this <tt>String</tt> object is compared to a substring
* A substring of this {@code String} object is compared to a substring
* of the argument other. The result is true if these substrings
* represent identical character sequences. The substring of this
* <tt>String</tt> object to be compared begins at index <tt>toffset</tt>
* and has length <tt>len</tt>. The substring of other to be compared
* begins at index <tt>ooffset</tt> and has length <tt>len</tt>. The
* result is <tt>false</tt> if and only if at least one of the following
* {@code String} object to be compared begins at index {@code toffset}
* and has length {@code len}. The substring of other to be compared
* begins at index {@code ooffset} and has length {@code len}. The
* result is {@code false} if and only if at least one of the following
* is true:
* <ul><li><tt>toffset</tt> is negative.
* <li><tt>ooffset</tt> is negative.
* <li><tt>toffset+len</tt> is greater than the length of this
* <tt>String</tt> object.
* <li><tt>ooffset+len</tt> is greater than the length of the other
* <ul><li>{@code toffset} is negative.
* <li>{@code ooffset} is negative.
* <li>{@code toffset+len} is greater than the length of this
* {@code String} object.
* <li>{@code ooffset+len} is greater than the length of the other
* argument.
* <li>There is some nonnegative integer <i>k</i> less than <tt>len</tt>
* <li>There is some nonnegative integer <i>k</i> less than {@code len}
* such that:
* <tt>this.charAt(toffset+<i>k</i>)&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>
*
* @param toffset the starting offset of the subregion in this string.
......@@ -1280,28 +1280,28 @@ public final class String
/**
* Tests if two string regions are equal.
* <p>
* A substring of this <tt>String</tt> object is compared to a substring
* of the argument <tt>other</tt>. The result is <tt>true</tt> if these
* A substring of this {@code String} object is compared to a substring
* of the argument {@code other}. The result is {@code true} if these
* substrings represent character sequences that are the same, ignoring
* case if and only if <tt>ignoreCase</tt> is true. The substring of
* this <tt>String</tt> object to be compared begins at index
* <tt>toffset</tt> and has length <tt>len</tt>. The substring of
* <tt>other</tt> to be compared begins at index <tt>ooffset</tt> and
* has length <tt>len</tt>. The result is <tt>false</tt> if and only if
* case if and only if {@code ignoreCase} is true. The substring of
* this {@code String} object to be compared begins at index
* {@code toffset} and has length {@code len}. The substring of
* {@code other} to be compared begins at index {@code ooffset} and
* has length {@code len}. The result is {@code false} if and only if
* at least one of the following is true:
* <ul><li><tt>toffset</tt> is negative.
* <li><tt>ooffset</tt> is negative.
* <li><tt>toffset+len</tt> is greater than the length of this
* <tt>String</tt> object.
* <li><tt>ooffset+len</tt> is greater than the length of the other
* <ul><li>{@code toffset} is negative.
* <li>{@code ooffset} is negative.
* <li>{@code toffset+len} is greater than the length of this
* {@code String} object.
* <li>{@code ooffset+len} is greater than the length of the other
* argument.
* <li><tt>ignoreCase</tt> is <tt>false</tt> and there is some nonnegative
* integer <i>k</i> less than <tt>len</tt> such that:
* <li>{@code ignoreCase} is {@code false} and there is some nonnegative
* integer <i>k</i> less than {@code len} such that:
* <blockquote><pre>
* this.charAt(toffset+k) != other.charAt(ooffset+k)
* </pre></blockquote>
* <li><tt>ignoreCase</tt> is <tt>true</tt> and there is some nonnegative
* integer <i>k</i> less than <tt>len</tt> such that:
* <li>{@code ignoreCase} is {@code true} and there is some nonnegative
* integer <i>k</i> less than {@code len} such that:
* <blockquote><pre>
* Character.toLowerCase(this.charAt(toffset+k)) !=
Character.toLowerCase(other.charAt(ooffset+k))
......@@ -1500,12 +1500,12 @@ public final class String
* of {@code ch} in the range from 0 to 0xFFFF (inclusive),
* this is the smallest value <i>k</i> such that:
* <blockquote><pre>
* (this.charAt(<i>k</i>) == ch) && (<i>k</i> &gt;= fromIndex)
* (this.charAt(<i>k</i>) == ch) {@code &&} (<i>k</i> &gt;= fromIndex)
* </pre></blockquote>
* is true. For other values of {@code ch}, it is the
* smallest value <i>k</i> such that:
* <blockquote><pre>
* (this.codePointAt(<i>k</i>) == ch) && (<i>k</i> &gt;= fromIndex)
* (this.codePointAt(<i>k</i>) == ch) {@code &&} (<i>k</i> &gt;= fromIndex)
* </pre></blockquote>
* is true. In either case, if no such character occurs in this
* string at or after position {@code fromIndex}, then
......@@ -1604,12 +1604,12 @@ public final class String
* from 0 to 0xFFFF (inclusive), the index returned is the largest
* value <i>k</i> such that:
* <blockquote><pre>
* (this.charAt(<i>k</i>) == ch) && (<i>k</i> &lt;= fromIndex)
* (this.charAt(<i>k</i>) == ch) {@code &&} (<i>k</i> &lt;= fromIndex)
* </pre></blockquote>
* is true. For other values of {@code ch}, it is the
* largest value <i>k</i> such that:
* <blockquote><pre>
* (this.codePointAt(<i>k</i>) == ch) && (<i>k</i> &lt;= fromIndex)
* (this.codePointAt(<i>k</i>) == ch) {@code &&} (<i>k</i> &lt;= fromIndex)
* </pre></blockquote>
* is true. In either case, if no such character occurs in this
* string at or before position {@code fromIndex}, then
......@@ -1690,7 +1690,7 @@ public final class String
*
* <p>The returned index is the smallest value <i>k</i> for which:
* <blockquote><pre>
* <i>k</i> &gt;= fromIndex && this.startsWith(str, <i>k</i>)
* <i>k</i> &gt;= fromIndex {@code &&} this.startsWith(str, <i>k</i>)
* </pre></blockquote>
* If no such value of <i>k</i> exists, then {@code -1} is returned.
*
......@@ -1799,7 +1799,7 @@ public final class String
*
* <p>The returned index is the largest value <i>k</i> for which:
* <blockquote><pre>
* <i>k</i> &lt;= fromIndex && this.startsWith(str, <i>k</i>)
* <i>k</i> {@code <=} fromIndex {@code &&} this.startsWith(str, <i>k</i>)
* </pre></blockquote>
* If no such value of <i>k</i> exists, then {@code -1} is returned.
*
......@@ -2080,17 +2080,18 @@ public final class String
* href="../util/regex/Pattern.html#sum">regular expression</a>.
*
* <p> An invocation of this method of the form
* <i>str</i><tt>.matches(</tt><i>regex</i><tt>)</tt> yields exactly the
* <i>str</i>{@code .matches(}<i>regex</i>{@code )} yields exactly the
* same result as the expression
*
* <blockquote><tt> {@link java.util.regex.Pattern}.{@link
* java.util.regex.Pattern#matches(String,CharSequence)
* matches}(</tt><i>regex</i><tt>,</tt> <i>str</i><tt>)</tt></blockquote>
* <blockquote>
* {@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#matches(String,CharSequence)
* matches(<i>regex</i>, <i>str</i>)}
* </blockquote>
*
* @param regex
* the regular expression to which this string is to be matched
*
* @return <tt>true</tt> if, and only if, this string matches the
* @return {@code true} if, and only if, this string matches the
* given regular expression
*
* @throws PatternSyntaxException
......@@ -2124,18 +2125,20 @@ public final class String
* given replacement.
*
* <p> An invocation of this method of the form
* <i>str</i><tt>.replaceFirst(</tt><i>regex</i><tt>,</tt> <i>repl</i><tt>)</tt>
* <i>str</i>{@code .replaceFirst(}<i>regex</i>{@code ,} <i>repl</i>{@code )}
* yields exactly the same result as the expression
*
* <blockquote><tt>
* {@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#compile
* compile}(</tt><i>regex</i><tt>).{@link
* java.util.regex.Pattern#matcher(java.lang.CharSequence)
* matcher}(</tt><i>str</i><tt>).{@link java.util.regex.Matcher#replaceFirst
* replaceFirst}(</tt><i>repl</i><tt>)</tt></blockquote>
* <blockquote>
* <code>
* {@link java.util.regex.Pattern}.{@link
* java.util.regex.Pattern#compile compile}(<i>regex</i>).{@link
* java.util.regex.Pattern#matcher(java.lang.CharSequence) matcher}(<i>str</i>).{@link
* java.util.regex.Matcher#replaceFirst replaceFirst}(<i>repl</i>)
* </code>
* </blockquote>
*
*<p>
* Note that backslashes (<tt>\</tt>) and dollar signs (<tt>$</tt>) in the
* Note that backslashes ({@code \}) and dollar signs ({@code $}) in the
* replacement string may cause the results to be different than if it were
* being treated as a literal replacement string; see
* {@link java.util.regex.Matcher#replaceFirst}.
......@@ -2147,7 +2150,7 @@ public final class String
* @param replacement
* the string to be substituted for the first match
*
* @return The resulting <tt>String</tt>
* @return The resulting {@code String}
*
* @throws PatternSyntaxException
* if the regular expression's syntax is invalid
......@@ -2167,18 +2170,20 @@ public final class String
* given replacement.
*
* <p> An invocation of this method of the form
* <i>str</i><tt>.replaceAll(</tt><i>regex</i><tt>,</tt> <i>repl</i><tt>)</tt>
* <i>str</i>{@code .replaceAll(}<i>regex</i>{@code ,} <i>repl</i>{@code )}
* yields exactly the same result as the expression
*
* <blockquote><tt>
* {@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#compile
* compile}(</tt><i>regex</i><tt>).{@link
* java.util.regex.Pattern#matcher(java.lang.CharSequence)
* matcher}(</tt><i>str</i><tt>).{@link java.util.regex.Matcher#replaceAll
* replaceAll}(</tt><i>repl</i><tt>)</tt></blockquote>
* <blockquote>
* <code>
* {@link java.util.regex.Pattern}.{@link
* java.util.regex.Pattern#compile compile}(<i>regex</i>).{@link
* java.util.regex.Pattern#matcher(java.lang.CharSequence) matcher}(<i>str</i>).{@link
* java.util.regex.Matcher#replaceAll replaceAll}(<i>repl</i>)
* </code>
* </blockquote>
*
*<p>
* Note that backslashes (<tt>\</tt>) and dollar signs (<tt>$</tt>) in the
* Note that backslashes ({@code \}) and dollar signs ({@code $}) in the
* replacement string may cause the results to be different than if it were
* being treated as a literal replacement string; see
* {@link java.util.regex.Matcher#replaceAll Matcher.replaceAll}.
......@@ -2190,7 +2195,7 @@ public final class String
* @param replacement
* the string to be substituted for each match
*
* @return The resulting <tt>String</tt>
* @return The resulting {@code String}
*
* @throws PatternSyntaxException
* if the regular expression's syntax is invalid
......@@ -2234,7 +2239,7 @@ public final class String
* expression does not match any part of the input then the resulting array
* has just one element, namely this string.
*
* <p> The <tt>limit</tt> parameter controls the number of times the
* <p> The {@code limit} parameter controls the number of times the
* pattern is applied and therefore affects the length of the resulting
* array. If the limit <i>n</i> is greater than zero then the pattern
* will be applied at most <i>n</i>&nbsp;-&nbsp;1 times, the array's
......@@ -2245,7 +2250,7 @@ public final class String
* the pattern will be applied as many times as possible, the array can
* have any length, and trailing empty strings will be discarded.
*
* <p> The string <tt>"boo:and:foo"</tt>, for example, yields the
* <p> The string {@code "boo:and:foo"}, for example, yields the
* following results with these parameters:
*
* <blockquote><table cellpadding=1 cellspacing=0 summary="Split example showing regex, limit, and result">
......@@ -2256,33 +2261,34 @@ public final class String
* </tr>
* <tr><td align=center>:</td>
* <td align=center>2</td>
* <td><tt>{ "boo", "and:foo" }</tt></td></tr>
* <td>{@code { "boo", "and:foo" }}</td></tr>
* <tr><td align=center>:</td>
* <td align=center>5</td>
* <td><tt>{ "boo", "and", "foo" }</tt></td></tr>
* <td>{@code { "boo", "and", "foo" }}</td></tr>
* <tr><td align=center>:</td>
* <td align=center>-2</td>
* <td><tt>{ "boo", "and", "foo" }</tt></td></tr>
* <td>{@code { "boo", "and", "foo" }}</td></tr>
* <tr><td align=center>o</td>
* <td align=center>5</td>
* <td><tt>{ "b", "", ":and:f", "", "" }</tt></td></tr>
* <td>{@code { "b", "", ":and:f", "", "" }}</td></tr>
* <tr><td align=center>o</td>
* <td align=center>-2</td>
* <td><tt>{ "b", "", ":and:f", "", "" }</tt></td></tr>
* <td>{@code { "b", "", ":and:f", "", "" }}</td></tr>
* <tr><td align=center>o</td>
* <td align=center>0</td>
* <td><tt>{ "b", "", ":and:f" }</tt></td></tr>
* <td>{@code { "b", "", ":and:f" }}</td></tr>
* </table></blockquote>
*
* <p> An invocation of this method of the form
* <i>str.</i><tt>split(</tt><i>regex</i><tt>,</tt>&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
*
* <blockquote>
* {@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#compile
* compile}<tt>(</tt><i>regex</i><tt>)</tt>.{@link
* java.util.regex.Pattern#split(java.lang.CharSequence,int)
* split}<tt>(</tt><i>str</i><tt>,</tt>&nbsp;<i>n</i><tt>)</tt>
* <code>
* {@link java.util.regex.Pattern}.{@link
* java.util.regex.Pattern#compile compile}(<i>regex</i>).{@link
* java.util.regex.Pattern#split(java.lang.CharSequence,int) split}(<i>str</i>,&nbsp;<i>n</i>)
* </code>
* </blockquote>
*
*
......@@ -2364,7 +2370,7 @@ public final class String
* argument of zero. Trailing empty strings are therefore not included in
* the resulting array.
*
* <p> The string <tt>"boo:and:foo"</tt>, for example, yields the following
* <p> The string {@code "boo:and:foo"}, for example, yields the following
* results with these expressions:
*
* <blockquote><table cellpadding=1 cellspacing=0 summary="Split examples showing regex and result">
......@@ -2373,9 +2379,9 @@ public final class String
* <th>Result</th>
* </tr>
* <tr><td align=center>:</td>
* <td><tt>{ "boo", "and", "foo" }</tt></td></tr>
* <td>{@code { "boo", "and", "foo" }}</td></tr>
* <tr><td align=center>o</td>
* <td><tt>{ "b", "", ":and:f" }</tt></td></tr>
* <td>{@code { "b", "", ":and:f" }}</td></tr>
* </table></blockquote>
*
*
......@@ -2815,7 +2821,7 @@ public final class String
* limited by the maximum dimension of a Java array as defined by
* <cite>The Java&trade; Virtual Machine Specification</cite>.
* The behaviour on a
* <tt>null</tt> argument depends on the <a
* {@code null} argument depends on the <a
* href="../util/Formatter.html#syntax">conversion</a>.
*
* @throws java.util.IllegalFormatException
......@@ -2828,7 +2834,7 @@ public final class String
* formatter class specification.
*
* @throws NullPointerException
* If the <tt>format</tt> is <tt>null</tt>
* If the {@code format} is {@code null}
*
* @return A formatted string
*
......@@ -2845,7 +2851,7 @@ public final class String
*
* @param l
* The {@linkplain java.util.Locale locale} to apply during
* formatting. If <tt>l</tt> is <tt>null</tt> then no localization
* formatting. If {@code l} is {@code null} then no localization
* is applied.
*
* @param format
......@@ -2859,7 +2865,7 @@ public final class String
* limited by the maximum dimension of a Java array as defined by
* <cite>The Java&trade; Virtual Machine Specification</cite>.
* The behaviour on a
* <tt>null</tt> argument depends on the <a
* {@code null} argument depends on the <a
* href="../util/Formatter.html#syntax">conversion</a>.
*
* @throws java.util.IllegalFormatException
......@@ -2872,7 +2878,7 @@ public final class String
* formatter class specification
*
* @throws NullPointerException
* If the <tt>format</tt> is <tt>null</tt>
* If the {@code format} is {@code null}
*
* @return A formatted string
*
......@@ -3143,7 +3149,7 @@ public final class String
* programmer should be aware that producing distinct integer results
* for unequal objects may improve the performance of hash tables.
* </ul>
* <p/>
* </p>
* The hash value will never be zero.
*
* @return a hash code value for this object.
......
......@@ -57,7 +57,7 @@ package java.lang;
* <p>
* In general, if sb refers to an instance of a {@code StringBuffer},
* then {@code sb.append(x)} has the same effect as
* {@code sb.insert(sb.length(),&nbsp;x)}.
* {@code sb.insert(sb.length(), x)}.
* <p>
* Whenever an operation occurs involving a source sequence (such as
* appending or inserting from a source sequence), this class synchronizes
......@@ -80,7 +80,7 @@ package java.lang;
*
* As of release JDK 5, this class has been supplemented with an equivalent
* class designed for use by a single thread, {@link StringBuilder}. The
* <tt>StringBuilder</tt> class should generally be used in preference to
* {@code StringBuilder} class should generally be used in preference to
* this one, as it supports all of the same operations but it is faster, as
* it performs no synchronization.
*
......@@ -262,17 +262,17 @@ package java.lang;
}
/**
* Appends the specified <tt>StringBuffer</tt> to this sequence.
* Appends the specified {@code StringBuffer} to this sequence.
* <p>
* The characters of the <tt>StringBuffer</tt> argument are appended,
* in order, to the contents of this <tt>StringBuffer</tt>, increasing the
* length of this <tt>StringBuffer</tt> by the length of the argument.
* If <tt>sb</tt> is <tt>null</tt>, then the four characters
* <tt>"null"</tt> are appended to this <tt>StringBuffer</tt>.
* The characters of the {@code StringBuffer} argument are appended,
* in order, to the contents of this {@code StringBuffer}, increasing the
* length of this {@code StringBuffer} by the length of the argument.
* If {@code sb} is {@code null}, then the four characters
* {@code "null"} are appended to this {@code StringBuffer}.
* <p>
* Let <i>n</i> be the length of the old character sequence, the one
* contained in the <tt>StringBuffer</tt> just prior to execution of the
* <tt>append</tt> method. Then the character at index <i>k</i> in
* contained in the {@code StringBuffer} just prior to execution of the
* {@code append} method. Then the character at index <i>k</i> in
* the new character sequence is equal to the character at index <i>k</i>
* in the old character sequence, if <i>k</i> is less than <i>n</i>;
* otherwise, it is equal to the character at index <i>k-n</i> in the
......@@ -281,7 +281,7 @@ package java.lang;
* This method synchronizes on {@code this}, the destination
* object, but does not synchronize on the source ({@code sb}).
*
* @param sb the <tt>StringBuffer</tt> to append.
* @param sb the {@code StringBuffer} to append.
* @return a reference to this object.
* @since 1.4
*/
......
......@@ -28,39 +28,39 @@ package java.lang;
/**
* A mutable sequence of characters. This class provides an API compatible
* with <code>StringBuffer</code>, but with no guarantee of synchronization.
* with {@code StringBuffer}, but with no guarantee of synchronization.
* This class is designed for use as a drop-in replacement for
* <code>StringBuffer</code> in places where the string buffer was being
* {@code StringBuffer} in places where the string buffer was being
* used by a single thread (as is generally the case). Where possible,
* it is recommended that this class be used in preference to
* <code>StringBuffer</code> as it will be faster under most implementations.
* {@code StringBuffer} as it will be faster under most implementations.
*
* <p>The principal operations on a <code>StringBuilder</code> are the
* <code>append</code> and <code>insert</code> methods, which are
* <p>The principal operations on a {@code StringBuilder} are the
* {@code append} and {@code insert} methods, which are
* overloaded so as to accept data of any type. Each effectively
* converts a given datum to a string and then appends or inserts the
* characters of that string to the string builder. The
* <code>append</code> method always adds these characters at the end
* of the builder; the <code>insert</code> method adds the characters at
* {@code append} method always adds these characters at the end
* of the builder; the {@code insert} method adds the characters at
* a specified point.
* <p>
* For example, if <code>z</code> refers to a string builder object
* whose current contents are "<code>start</code>", then
* the method call <code>z.append("le")</code> would cause the string
* builder to contain "<code>startle</code>", whereas
* <code>z.insert(4, "le")</code> would alter the string builder to
* contain "<code>starlet</code>".
* For example, if {@code z} refers to a string builder object
* whose current contents are "{@code start}", then
* the method call {@code z.append("le")} would cause the string
* builder to contain "{@code startle}", whereas
* {@code z.insert(4, "le")} would alter the string builder to
* contain "{@code starlet}".
* <p>
* In general, if sb refers to an instance of a {@code StringBuilder},
* then {@code sb.append(x)} has the same effect as
* {@code sb.insert(sb.length(), x)}.
* <p>
* In general, if sb refers to an instance of a <code>StringBuilder</code>,
* then <code>sb.append(x)</code> has the same effect as
* <code>sb.insert(sb.length(),&nbsp;x)</code>.
*
* Every string builder has a capacity. As long as the length of the
* character sequence contained in the string builder does not exceed
* the capacity, it is not necessary to allocate a new internal
* buffer. If the internal buffer overflows, it is automatically made larger.
*
* <p>Instances of <code>StringBuilder</code> are not safe for
* <p>Instances of {@code StringBuilder} are not safe for
* use by multiple threads. If such synchronization is required then it is
* recommended that {@link java.lang.StringBuffer} be used.
*
......@@ -87,11 +87,11 @@ public final class StringBuilder
/**
* Constructs a string builder with no characters in it and an
* initial capacity specified by the <code>capacity</code> argument.
* initial capacity specified by the {@code capacity} argument.
*
* @param capacity the initial capacity.
* @throws NegativeArraySizeException if the <code>capacity</code>
* argument is less than <code>0</code>.
* @throws NegativeArraySizeException if the {@code capacity}
* argument is less than {@code 0}.
*/
public StringBuilder(int capacity) {
super(capacity);
......@@ -100,10 +100,10 @@ public final class StringBuilder
/**
* Constructs a string builder initialized to the contents of the
* specified string. The initial capacity of the string builder is
* <code>16</code> plus the length of the string argument.
* {@code 16} plus the length of the string argument.
*
* @param str the initial contents of the buffer.
* @throws NullPointerException if <code>str</code> is <code>null</code>
* @throws NullPointerException if {@code str} is {@code null}
*/
public StringBuilder(String str) {
super(str.length() + 16);
......@@ -112,12 +112,12 @@ public final class StringBuilder
/**
* Constructs a string builder that contains the same characters
* as the specified <code>CharSequence</code>. The initial capacity of
* the string builder is <code>16</code> plus the length of the
* <code>CharSequence</code> argument.
* as the specified {@code CharSequence}. The initial capacity of
* the string builder is {@code 16} plus the length of the
* {@code CharSequence} argument.
*
* @param seq the sequence to copy.
* @throws NullPointerException if <code>seq</code> is <code>null</code>
* @throws NullPointerException if {@code seq} is {@code null}
*/
public StringBuilder(CharSequence seq) {
this(seq.length() + 16);
......@@ -136,22 +136,22 @@ public final class StringBuilder
}
/**
* Appends the specified <tt>StringBuffer</tt> to this sequence.
* Appends the specified {@code StringBuffer} to this sequence.
* <p>
* The characters of the <tt>StringBuffer</tt> argument are appended,
* The characters of the {@code StringBuffer} argument are appended,
* in order, to this sequence, increasing the
* length of this sequence by the length of the argument.
* If <tt>sb</tt> is <tt>null</tt>, then the four characters
* <tt>"null"</tt> are appended to this sequence.
* If {@code sb} is {@code null}, then the four characters
* {@code "null"} are appended to this sequence.
* <p>
* Let <i>n</i> be the length of this character sequence just prior to
* execution of the <tt>append</tt> method. Then the character at index
* execution of the {@code append} method. Then the character at index
* <i>k</i> in the new character sequence is equal to the character at
* index <i>k</i> in the old character sequence, if <i>k</i> is less than
* <i>n</i>; otherwise, it is equal to the character at index <i>k-n</i>
* in the argument <code>sb</code>.
* in the argument {@code sb}.
*
* @param sb the <tt>StringBuffer</tt> to append.
* @param sb the {@code StringBuffer} to append.
* @return a reference to this object.
*/
public StringBuilder append(StringBuffer sb) {
......@@ -418,13 +418,13 @@ public final class StringBuilder
}
/**
* Save the state of the <tt>StringBuilder</tt> instance to a stream
* Save the state of the {@code StringBuilder} instance to a stream
* (that is, serialize it).
*
* @serialData the number of characters currently stored in the string
* builder (<tt>int</tt>), followed by the characters in the
* string builder (<tt>char[]</tt>). The length of the
* <tt>char</tt> array may be greater than the number of
* builder ({@code int}), followed by the characters in the
* string builder ({@code char[]}). The length of the
* {@code char} array may be greater than the number of
* characters currently stored in the string builder, in which
* case extra characters are ignored.
*/
......
/*
* Copyright (c) 1994, 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -26,7 +26,7 @@
package java.lang;
/**
* Thrown by <code>String</code> methods to indicate that an index
* Thrown by {@code String} methods to indicate that an index
* is either negative or greater than the size of the string. For
* some methods such as the charAt method, this exception also is
* thrown when the index is equal to the size of the string.
......@@ -40,7 +40,7 @@ class StringIndexOutOfBoundsException extends IndexOutOfBoundsException {
private static final long serialVersionUID = -6762910422159637258L;
/**
* Constructs a <code>StringIndexOutOfBoundsException</code> with no
* Constructs a {@code StringIndexOutOfBoundsException} with no
* detail message.
*
* @since JDK1.0.
......@@ -50,7 +50,7 @@ class StringIndexOutOfBoundsException extends IndexOutOfBoundsException {
}
/**
* Constructs a <code>StringIndexOutOfBoundsException</code> with
* Constructs a {@code StringIndexOutOfBoundsException} with
* the specified detail message.
*
* @param s the detail message.
......@@ -60,7 +60,7 @@ class StringIndexOutOfBoundsException extends IndexOutOfBoundsException {
}
/**
* Constructs a new <code>StringIndexOutOfBoundsException</code>
* Constructs a new {@code StringIndexOutOfBoundsException}
* class with an argument indicating the illegal index.
*
* @param index the illegal index.
......
/*
* 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -25,6 +25,8 @@
package java.security;
import javax.security.auth.Subject;
/**
* This interface represents the abstract notion of a principal, which
* can be used to represent any entity, such as an individual, a
......@@ -45,7 +47,6 @@ public interface Principal {
*
* @return true if the principal passed in is the same as that
* encapsulated by this principal, and false otherwise.
*/
public boolean equals(Object another);
......@@ -69,4 +70,24 @@ public interface Principal {
* @return the name of this principal.
*/
public String getName();
/**
* Returns true if the specified subject is implied by this principal.
*
* <p>The default implementation of this method returns true if
* {@code subject} is non-null and contains at least one principal that
* is equal to this principal.
*
* <p>Subclasses may override this with a different implementation, if
* necessary.
*
* @return true if {@code subject} is non-null and is
* implied by this principal, or false otherwise.
* @since 1.8
*/
public default boolean implies(Subject subject) {
if (subject == null)
return false;
return subject.getPrincipals().contains(this);
}
}
......@@ -2611,6 +2611,7 @@ public class ForkJoinPool extends AbstractExecutorService {
* {@link #shutdown} or {@link #shutdownNow}.
*
* @return the common pool instance
* @since 1.8
*/
public static ForkJoinPool commonPool() {
// assert commonPool != null : "static init error";
......@@ -2793,6 +2794,7 @@ public class ForkJoinPool extends AbstractExecutorService {
* Returns the targeted parallelism level of the common pool.
*
* @return the targeted parallelism level of the common pool
* @since 1.8
*/
public static int getCommonPoolParallelism() {
return commonPoolParallelism;
......
......@@ -111,7 +111,7 @@ public class AtomicBoolean implements java.io.Serializable {
*
* @param expect the expected value
* @param update the new value
* @return true if successful.
* @return true if successful
*/
public boolean weakCompareAndSet(boolean expect, boolean update) {
int e = expect ? 1 : 0;
......@@ -146,16 +146,16 @@ public class AtomicBoolean implements java.io.Serializable {
* @return the previous value
*/
public final boolean getAndSet(boolean newValue) {
for (;;) {
boolean current = get();
if (compareAndSet(current, newValue))
return current;
}
boolean prev;
do {
prev = get();
} while (!compareAndSet(prev, newValue));
return prev;
}
/**
* Returns the String representation of the current value.
* @return the String representation of the current value.
* @return the String representation of the current value
*/
public String toString() {
return Boolean.toString(get());
......
......@@ -115,11 +115,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
* @return the previous value
*/
public final int getAndSet(int newValue) {
for (;;) {
int current = get();
if (compareAndSet(current, newValue))
return current;
}
return unsafe.getAndSetInt(this, valueOffset, newValue);
}
/**
......@@ -145,7 +141,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
*
* @param expect the expected value
* @param update the new value
* @return true if successful.
* @return true if successful
*/
public final boolean weakCompareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
......@@ -157,12 +153,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
* @return the previous value
*/
public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
return getAndAdd(1);
}
/**
......@@ -171,12 +162,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
* @return the previous value
*/
public final int getAndDecrement() {
for (;;) {
int current = get();
int next = current - 1;
if (compareAndSet(current, next))
return current;
}
return getAndAdd(-1);
}
/**
......@@ -186,12 +172,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
* @return the previous value
*/
public final int getAndAdd(int delta) {
for (;;) {
int current = get();
int next = current + delta;
if (compareAndSet(current, next))
return current;
}
return unsafe.getAndAddInt(this, valueOffset, delta);
}
/**
......@@ -200,12 +181,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
* @return the updated value
*/
public final int incrementAndGet() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return next;
}
return getAndAdd(1) + 1;
}
/**
......@@ -214,12 +190,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
* @return the updated value
*/
public final int decrementAndGet() {
for (;;) {
int current = get();
int next = current - 1;
if (compareAndSet(current, next))
return next;
}
return getAndAdd(-1) - 1;
}
/**
......@@ -229,17 +200,12 @@ public class AtomicInteger extends Number implements java.io.Serializable {
* @return the updated value
*/
public final int addAndGet(int delta) {
for (;;) {
int current = get();
int next = current + delta;
if (compareAndSet(current, next))
return next;
}
return getAndAdd(delta) + delta;
}
/**
* Returns the String representation of the current value.
* @return the String representation of the current value.
* @return the String representation of the current value
*/
public String toString() {
return Integer.toString(get());
......
......@@ -145,12 +145,7 @@ public class AtomicIntegerArray implements java.io.Serializable {
* @return the previous value
*/
public final int getAndSet(int i, int newValue) {
long offset = checkedByteOffset(i);
while (true) {
int current = getRaw(offset);
if (compareAndSetRaw(offset, current, newValue))
return current;
}
return unsafe.getAndSetInt(array, checkedByteOffset(i), newValue);
}
/**
......@@ -182,7 +177,7 @@ public class AtomicIntegerArray implements java.io.Serializable {
* @param i the index
* @param expect the expected value
* @param update the new value
* @return true if successful.
* @return true if successful
*/
public final boolean weakCompareAndSet(int i, int expect, int update) {
return compareAndSet(i, expect, update);
......@@ -216,12 +211,7 @@ public class AtomicIntegerArray implements java.io.Serializable {
* @return the previous value
*/
public final int getAndAdd(int i, int delta) {
long offset = checkedByteOffset(i);
while (true) {
int current = getRaw(offset);
if (compareAndSetRaw(offset, current, current + delta))
return current;
}
return unsafe.getAndAddInt(array, checkedByteOffset(i), delta);
}
/**
......@@ -231,7 +221,7 @@ public class AtomicIntegerArray implements java.io.Serializable {
* @return the updated value
*/
public final int incrementAndGet(int i) {
return addAndGet(i, 1);
return getAndAdd(i, 1) + 1;
}
/**
......@@ -241,7 +231,7 @@ public class AtomicIntegerArray implements java.io.Serializable {
* @return the updated value
*/
public final int decrementAndGet(int i) {
return addAndGet(i, -1);
return getAndAdd(i, -1) - 1;
}
/**
......@@ -252,13 +242,7 @@ public class AtomicIntegerArray implements java.io.Serializable {
* @return the updated value
*/
public final int addAndGet(int i, int delta) {
long offset = checkedByteOffset(i);
while (true) {
int current = getRaw(offset);
int next = current + delta;
if (compareAndSetRaw(offset, current, next))
return next;
}
return getAndAdd(i, delta) + delta;
}
/**
......
......@@ -159,11 +159,11 @@ public abstract class AtomicIntegerFieldUpdater<T> {
* @return the previous value
*/
public int getAndSet(T obj, int newValue) {
for (;;) {
int current = get(obj);
if (compareAndSet(obj, current, newValue))
return current;
}
int prev;
do {
prev = get(obj);
} while (!compareAndSet(obj, prev, newValue));
return prev;
}
/**
......@@ -174,12 +174,12 @@ public abstract class AtomicIntegerFieldUpdater<T> {
* @return the previous value
*/
public int getAndIncrement(T obj) {
for (;;) {
int current = get(obj);
int next = current + 1;
if (compareAndSet(obj, current, next))
return current;
}
int prev, next;
do {
prev = get(obj);
next = prev + 1;
} while (!compareAndSet(obj, prev, next));
return prev;
}
/**
......@@ -190,12 +190,12 @@ public abstract class AtomicIntegerFieldUpdater<T> {
* @return the previous value
*/
public int getAndDecrement(T obj) {
for (;;) {
int current = get(obj);
int next = current - 1;
if (compareAndSet(obj, current, next))
return current;
}
int prev, next;
do {
prev = get(obj);
next = prev - 1;
} while (!compareAndSet(obj, prev, next));
return prev;
}
/**
......@@ -207,12 +207,12 @@ public abstract class AtomicIntegerFieldUpdater<T> {
* @return the previous value
*/
public int getAndAdd(T obj, int delta) {
for (;;) {
int current = get(obj);
int next = current + delta;
if (compareAndSet(obj, current, next))
return current;
}
int prev, next;
do {
prev = get(obj);
next = prev + delta;
} while (!compareAndSet(obj, prev, next));
return prev;
}
/**
......@@ -223,12 +223,12 @@ public abstract class AtomicIntegerFieldUpdater<T> {
* @return the updated value
*/
public int incrementAndGet(T obj) {
for (;;) {
int current = get(obj);
int next = current + 1;
if (compareAndSet(obj, current, next))
return next;
}
int prev, next;
do {
prev = get(obj);
next = prev + 1;
} while (!compareAndSet(obj, prev, next));
return next;
}
/**
......@@ -239,12 +239,12 @@ public abstract class AtomicIntegerFieldUpdater<T> {
* @return the updated value
*/
public int decrementAndGet(T obj) {
for (;;) {
int current = get(obj);
int next = current - 1;
if (compareAndSet(obj, current, next))
return next;
}
int prev, next;
do {
prev = get(obj);
next = prev - 1;
} while (!compareAndSet(obj, prev, next));
return next;
}
/**
......@@ -256,12 +256,12 @@ public abstract class AtomicIntegerFieldUpdater<T> {
* @return the updated value
*/
public int addAndGet(T obj, int delta) {
for (;;) {
int current = get(obj);
int next = current + delta;
if (compareAndSet(obj, current, next))
return next;
}
int prev, next;
do {
prev = get(obj);
next = prev + delta;
} while (!compareAndSet(obj, prev, next));
return next;
}
/**
......@@ -361,6 +361,36 @@ public abstract class AtomicIntegerFieldUpdater<T> {
return unsafe.getIntVolatile(obj, offset);
}
public int getAndSet(T obj, int newValue) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
return unsafe.getAndSetInt(obj, offset, newValue);
}
public int getAndIncrement(T obj) {
return getAndAdd(obj, 1);
}
public int getAndDecrement(T obj) {
return getAndAdd(obj, -1);
}
public int getAndAdd(T obj, int delta) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
return unsafe.getAndAddInt(obj, offset, delta);
}
public int incrementAndGet(T obj) {
return getAndAdd(obj, 1) + 1;
}
public int decrementAndGet(T obj) {
return getAndAdd(obj, -1) - 1;
}
public int addAndGet(T obj, int delta) {
return getAndAdd(obj, delta) + delta;
}
private void ensureProtectedAccess(T obj) {
if (cclass.isInstance(obj)) {
return;
......
......@@ -129,11 +129,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
* @return the previous value
*/
public final long getAndSet(long newValue) {
while (true) {
long current = get();
if (compareAndSet(current, newValue))
return current;
}
return unsafe.getAndSetLong(this, valueOffset, newValue);
}
/**
......@@ -159,7 +155,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
*
* @param expect the expected value
* @param update the new value
* @return true if successful.
* @return true if successful
*/
public final boolean weakCompareAndSet(long expect, long update) {
return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
......@@ -171,12 +167,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
* @return the previous value
*/
public final long getAndIncrement() {
while (true) {
long current = get();
long next = current + 1;
if (compareAndSet(current, next))
return current;
}
return getAndAdd(1);
}
/**
......@@ -185,12 +176,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
* @return the previous value
*/
public final long getAndDecrement() {
while (true) {
long current = get();
long next = current - 1;
if (compareAndSet(current, next))
return current;
}
return getAndAdd(-1);
}
/**
......@@ -200,12 +186,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
* @return the previous value
*/
public final long getAndAdd(long delta) {
while (true) {
long current = get();
long next = current + delta;
if (compareAndSet(current, next))
return current;
}
return unsafe.getAndAddLong(this, valueOffset, delta);
}
/**
......@@ -214,12 +195,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
* @return the updated value
*/
public final long incrementAndGet() {
for (;;) {
long current = get();
long next = current + 1;
if (compareAndSet(current, next))
return next;
}
return getAndAdd(1) + 1;
}
/**
......@@ -228,12 +204,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
* @return the updated value
*/
public final long decrementAndGet() {
for (;;) {
long current = get();
long next = current - 1;
if (compareAndSet(current, next))
return next;
}
return getAndAdd(-1) - 1;
}
/**
......@@ -243,17 +214,12 @@ public class AtomicLong extends Number implements java.io.Serializable {
* @return the updated value
*/
public final long addAndGet(long delta) {
for (;;) {
long current = get();
long next = current + delta;
if (compareAndSet(current, next))
return next;
}
return getAndAdd(delta) + delta;
}
/**
* Returns the String representation of the current value.
* @return the String representation of the current value.
* @return the String representation of the current value
*/
public String toString() {
return Long.toString(get());
......
......@@ -144,12 +144,7 @@ public class AtomicLongArray implements java.io.Serializable {
* @return the previous value
*/
public final long getAndSet(int i, long newValue) {
long offset = checkedByteOffset(i);
while (true) {
long current = getRaw(offset);
if (compareAndSetRaw(offset, current, newValue))
return current;
}
return unsafe.getAndSetLong(array, checkedByteOffset(i), newValue);
}
/**
......@@ -181,7 +176,7 @@ public class AtomicLongArray implements java.io.Serializable {
* @param i the index
* @param expect the expected value
* @param update the new value
* @return true if successful.
* @return true if successful
*/
public final boolean weakCompareAndSet(int i, long expect, long update) {
return compareAndSet(i, expect, update);
......@@ -215,12 +210,7 @@ public class AtomicLongArray implements java.io.Serializable {
* @return the previous value
*/
public final long getAndAdd(int i, long delta) {
long offset = checkedByteOffset(i);
while (true) {
long current = getRaw(offset);
if (compareAndSetRaw(offset, current, current + delta))
return current;
}
return unsafe.getAndAddLong(array, checkedByteOffset(i), delta);
}
/**
......@@ -230,7 +220,7 @@ public class AtomicLongArray implements java.io.Serializable {
* @return the updated value
*/
public final long incrementAndGet(int i) {
return addAndGet(i, 1);
return getAndAdd(i, 1) + 1;
}
/**
......@@ -240,7 +230,7 @@ public class AtomicLongArray implements java.io.Serializable {
* @return the updated value
*/
public final long decrementAndGet(int i) {
return addAndGet(i, -1);
return getAndAdd(i, -1) - 1;
}
/**
......@@ -251,13 +241,7 @@ public class AtomicLongArray implements java.io.Serializable {
* @return the updated value
*/
public long addAndGet(int i, long delta) {
long offset = checkedByteOffset(i);
while (true) {
long current = getRaw(offset);
long next = current + delta;
if (compareAndSetRaw(offset, current, next))
return next;
}
return getAndAdd(i, delta) + delta;
}
/**
......
......@@ -98,7 +98,7 @@ public abstract class AtomicLongFieldUpdater<T> {
* @param obj An object whose field to conditionally set
* @param expect the expected value
* @param update the new value
* @return true if successful.
* @return true if successful
* @throws ClassCastException if {@code obj} is not an instance
* of the class possessing the field established in the constructor.
*/
......@@ -118,7 +118,7 @@ public abstract class AtomicLongFieldUpdater<T> {
* @param obj An object whose field to conditionally set
* @param expect the expected value
* @param update the new value
* @return true if successful.
* @return true if successful
* @throws ClassCastException if {@code obj} is not an instance
* of the class possessing the field established in the constructor.
*/
......@@ -162,11 +162,11 @@ public abstract class AtomicLongFieldUpdater<T> {
* @return the previous value
*/
public long getAndSet(T obj, long newValue) {
for (;;) {
long current = get(obj);
if (compareAndSet(obj, current, newValue))
return current;
}
long prev;
do {
prev = get(obj);
} while (!compareAndSet(obj, prev, newValue));
return prev;
}
/**
......@@ -177,12 +177,12 @@ public abstract class AtomicLongFieldUpdater<T> {
* @return the previous value
*/
public long getAndIncrement(T obj) {
for (;;) {
long current = get(obj);
long next = current + 1;
if (compareAndSet(obj, current, next))
return current;
}
long prev, next;
do {
prev = get(obj);
next = prev + 1;
} while (!compareAndSet(obj, prev, next));
return prev;
}
/**
......@@ -193,12 +193,12 @@ public abstract class AtomicLongFieldUpdater<T> {
* @return the previous value
*/
public long getAndDecrement(T obj) {
for (;;) {
long current = get(obj);
long next = current - 1;
if (compareAndSet(obj, current, next))
return current;
}
long prev, next;
do {
prev = get(obj);
next = prev - 1;
} while (!compareAndSet(obj, prev, next));
return prev;
}
/**
......@@ -210,12 +210,12 @@ public abstract class AtomicLongFieldUpdater<T> {
* @return the previous value
*/
public long getAndAdd(T obj, long delta) {
for (;;) {
long current = get(obj);
long next = current + delta;
if (compareAndSet(obj, current, next))
return current;
}
long prev, next;
do {
prev = get(obj);
next = prev + delta;
} while (!compareAndSet(obj, prev, next));
return prev;
}
/**
......@@ -226,12 +226,12 @@ public abstract class AtomicLongFieldUpdater<T> {
* @return the updated value
*/
public long incrementAndGet(T obj) {
for (;;) {
long current = get(obj);
long next = current + 1;
if (compareAndSet(obj, current, next))
return next;
}
long prev, next;
do {
prev = get(obj);
next = prev + 1;
} while (!compareAndSet(obj, prev, next));
return next;
}
/**
......@@ -242,12 +242,12 @@ public abstract class AtomicLongFieldUpdater<T> {
* @return the updated value
*/
public long decrementAndGet(T obj) {
for (;;) {
long current = get(obj);
long next = current - 1;
if (compareAndSet(obj, current, next))
return next;
}
long prev, next;
do {
prev = get(obj);
next = prev - 1;
} while (!compareAndSet(obj, prev, next));
return next;
}
/**
......@@ -259,12 +259,12 @@ public abstract class AtomicLongFieldUpdater<T> {
* @return the updated value
*/
public long addAndGet(T obj, long delta) {
for (;;) {
long current = get(obj);
long next = current + delta;
if (compareAndSet(obj, current, next))
return next;
}
long prev, next;
do {
prev = get(obj);
next = prev + delta;
} while (!compareAndSet(obj, prev, next));
return next;
}
private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
......@@ -345,6 +345,36 @@ public abstract class AtomicLongFieldUpdater<T> {
return unsafe.getLongVolatile(obj, offset);
}
public long getAndSet(T obj, long newValue) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
return unsafe.getAndSetLong(obj, offset, newValue);
}
public long getAndIncrement(T obj) {
return getAndAdd(obj, 1);
}
public long getAndDecrement(T obj) {
return getAndAdd(obj, -1);
}
public long getAndAdd(T obj, long delta) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
return unsafe.getAndAddLong(obj, offset, delta);
}
public long incrementAndGet(T obj) {
return getAndAdd(obj, 1) + 1;
}
public long decrementAndGet(T obj) {
return getAndAdd(obj, -1) - 1;
}
public long addAndGet(T obj, long delta) {
return getAndAdd(obj, delta) + delta;
}
private void ensureProtectedAccess(T obj) {
if (cclass.isInstance(obj)) {
return;
......
......@@ -124,7 +124,7 @@ public class AtomicReference<V> implements java.io.Serializable {
*
* @param expect the expected value
* @param update the new value
* @return true if successful.
* @return true if successful
*/
public final boolean weakCompareAndSet(V expect, V update) {
return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
......@@ -136,17 +136,14 @@ public class AtomicReference<V> implements java.io.Serializable {
* @param newValue the new value
* @return the previous value
*/
@SuppressWarnings("unchecked")
public final V getAndSet(V newValue) {
while (true) {
V x = get();
if (compareAndSet(x, newValue))
return x;
}
return (V)unsafe.getAndSetObject(this, valueOffset, newValue);
}
/**
* Returns the String representation of the current value.
* @return the String representation of the current value.
* @return the String representation of the current value
*/
public String toString() {
return String.valueOf(get());
......
......@@ -159,13 +159,9 @@ public class AtomicReferenceArray<E> implements java.io.Serializable {
* @param newValue the new value
* @return the previous value
*/
@SuppressWarnings("unchecked")
public final E getAndSet(int i, E newValue) {
long offset = checkedByteOffset(i);
while (true) {
E current = getRaw(offset);
if (compareAndSetRaw(offset, current, newValue))
return current;
}
return (E)unsafe.getAndSetObject(array, checkedByteOffset(i), newValue);
}
/**
......@@ -197,7 +193,7 @@ public class AtomicReferenceArray<E> implements java.io.Serializable {
* @param i the index
* @param expect the expected value
* @param update the new value
* @return true if successful.
* @return true if successful
*/
public final boolean weakCompareAndSet(int i, E expect, E update) {
return compareAndSet(i, expect, update);
......
......@@ -116,7 +116,7 @@ public abstract class AtomicReferenceFieldUpdater<T, V> {
* @param obj An object whose field to conditionally set
* @param expect the expected value
* @param update the new value
* @return true if successful.
* @return true if successful
*/
public abstract boolean compareAndSet(T obj, V expect, V update);
......@@ -134,7 +134,7 @@ public abstract class AtomicReferenceFieldUpdater<T, V> {
* @param obj An object whose field to conditionally set
* @param expect the expected value
* @param update the new value
* @return true if successful.
* @return true if successful
*/
public abstract boolean weakCompareAndSet(T obj, V expect, V update);
......@@ -176,11 +176,11 @@ public abstract class AtomicReferenceFieldUpdater<T, V> {
* @return the previous value
*/
public V getAndSet(T obj, V newValue) {
for (;;) {
V current = get(obj);
if (compareAndSet(obj, current, newValue))
return current;
}
V prev;
do {
prev = get(obj);
} while (!compareAndSet(obj, prev, newValue));
return prev;
}
private static final class AtomicReferenceFieldUpdaterImpl<T,V>
......@@ -321,6 +321,15 @@ public abstract class AtomicReferenceFieldUpdater<T, V> {
return (V)unsafe.getObjectVolatile(obj, offset);
}
@SuppressWarnings("unchecked")
public V getAndSet(T obj, V newValue) {
if (obj == null || obj.getClass() != tclass || cclass != null ||
(newValue != null && vclass != null &&
vclass != newValue.getClass()))
updateCheck(obj, newValue);
return (V)unsafe.getAndSetObject(obj, offset, newValue);
}
private void ensureProtectedAccess(T obj) {
if (cclass.isInstance(obj)) {
return;
......
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -104,17 +104,30 @@ import sun.security.jca.*;
* must be supplied to GCM/CCM implementations (via the {@code
* updateAAD} methods) <b>before</b> the ciphertext is processed (via
* the {@code update} and {@code doFinal} methods).
*
* <p>
* Note that GCM mode has a uniqueness requirement on IVs used in
* encryption with a given key. When IVs are repeated for GCM
* encryption, such usages are subject to forgery attacks. Thus, after
* each encryption operation using GCM mode, callers should re-initialize
* the cipher objects with GCM parameters which has a different IV value.
* <pre>
* GCMParameterSpec s = new GCMParameterSpec(...);
* GCMParameterSpec s = ...;
* cipher.init(..., s);
*
* // If the GCMParameterSpec is needed again
* cipher.getParameters().getParameterSpec(GCMParameterSpec.class));
* // If the GCM parameters were generated by the provider, it can
* // be retrieved by:
* // cipher.getParameters().getParameterSpec(GCMParameterSpec.class);
*
* cipher.updateAAD(...); // AAD
* cipher.update(...); // Multi-part update
* cipher.doFinal(...); // conclusion of operation
*
* // Use a different IV value for every encryption
* byte[] newIv = ...;
* s = new GCMParameterSpec(s.getTLen(), newIv);
* cipher.init(..., s);
* ...
*
* </pre>
* Every implementation of the Java platform is required to support
* the following standard <code>Cipher</code> transformations with the keysizes
......
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -43,7 +43,7 @@ import java.security.spec.AlgorithmParameterSpec;
* (Additional Authenticated Data (AAD), Keys, block ciphers,
* plain/ciphertext and authentication tags) are handled in the {@code
* Cipher} class.
<p>
* <p>
* Please see <a href="http://www.ietf.org/rfc/rfc5116.txt"> RFC 5116
* </a> for more information on the Authenticated Encryption with
* Associated Data (AEAD) algorithm, and <a href=
......
......@@ -3953,7 +3953,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
break;
case TableModelEvent.INSERT:
modelSelection.insertIndexInterval(change.startModelIndex,
change.endModelIndex,
change.length,
true);
break;
default:
......
/*
* Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -409,6 +409,15 @@ public enum LauncherHelper {
if (mainValue == null) {
abort(null, "java.launcher.jar.error3", jarname);
}
/*
* Hand off to FXHelper if it detects a JavaFX application
* This must be done after ensuring a Main-Class entry
* exists to enforce compliance with the jar specification
*/
if (mainAttrs.containsKey(
new Attributes.Name(FXHelper.JAVAFX_APPLICATION_MARKER))) {
return FXHelper.class.getName();
}
return mainValue.trim();
} catch (IOException ioe) {
abort(ioe, "java.launcher.jar.error1", jarname);
......@@ -483,26 +492,23 @@ public enum LauncherHelper {
} catch (NoClassDefFoundError | ClassNotFoundException cnfe) {
abort(cnfe, "java.launcher.cls.error1", cn);
}
// set to mainClass, FXHelper may return something else
// set to mainClass
appClass = mainClass;
Method m = getMainMethod(mainClass);
if (m != null) {
// this will abort if main method has the wrong signature
validateMainMethod(m);
return mainClass;
}
// Check if FXHelper can launch it using the FX launcher
Class<?> fxClass = FXHelper.getFXMainClass(mainClass);
if (fxClass != null) {
return fxClass;
/*
* Check if FXHelper can launch it using the FX launcher. In an FX app,
* the main class may or may not have a main method, so do this before
* validating the main class.
*/
if (mainClass.equals(FXHelper.class) ||
FXHelper.doesExtendFXApplication(mainClass)) {
// Will abort() if there are problems with the FX runtime
FXHelper.setFXLaunchParameters(what, mode);
return FXHelper.class;
}
// not an FX application either, abort with an error
abort(null, "java.launcher.cls.error4", mainClass.getName(),
FXHelper.JAVAFX_APPLICATION_CLASS_NAME);
return null; // avoid compiler error...
validateMainClass(mainClass);
return mainClass;
}
/*
......@@ -515,16 +521,18 @@ public enum LauncherHelper {
return appClass;
}
// Check for main method or return null if not found
static Method getMainMethod(Class<?> clazz) {
// Check the existence and signature of main and abort if incorrect
static void validateMainClass(Class<?> mainClass) {
Method mainMethod;
try {
return clazz.getMethod("main", String[].class);
} catch (NoSuchMethodException nsme) {}
return null;
}
mainMethod = mainClass.getMethod("main", String[].class);
} catch (NoSuchMethodException nsme) {
// invalid main or not FX application, abort with an error
abort(null, "java.launcher.cls.error4", mainClass.getName(),
FXHelper.JAVAFX_APPLICATION_CLASS_NAME);
return; // Avoid compiler issues
}
// Check the signature of main and abort if it's incorrect
static void validateMainMethod(Method mainMethod) {
/*
* getMethod (above) will choose the correct method, based
* on its name and parameter type, however, we still have to
......@@ -644,41 +652,78 @@ public enum LauncherHelper {
}
static final class FXHelper {
// Marker entry in jar manifest that designates a JavaFX application jar
private static final String JAVAFX_APPLICATION_MARKER =
"JavaFX-Application-Class";
private static final String JAVAFX_APPLICATION_CLASS_NAME =
"javafx.application.Application";
private static final String JAVAFX_LAUNCHER_CLASS_NAME =
"com.sun.javafx.application.LauncherImpl";
/*
* The launch method used to invoke the JavaFX launcher. These must
* match the strings used in the launchApplication method.
*
* Command line JavaFX-App-Class Launch mode FX Launch mode
* java -cp fxapp.jar FXClass N/A LM_CLASS "LM_CLASS"
* java -cp somedir FXClass N/A LM_CLASS "LM_CLASS"
* java -jar fxapp.jar Present LM_JAR "LM_JAR"
* java -jar fxapp.jar Not Present LM_JAR "LM_JAR"
*/
private static final String JAVAFX_LAUNCH_MODE_CLASS = "LM_CLASS";
private static final String JAVAFX_LAUNCH_MODE_JAR = "LM_JAR";
/*
* FX application launcher and launch method, so we can launch
* applications with no main method.
*/
private static String fxLaunchName = null;
private static String fxLaunchMode = null;
private static Class<?> fxLauncherClass = null;
private static Method fxLauncherMethod = null;
/*
* We can assume that the class does NOT have a main method or it would
* have been handled already. We do, however, need to check if the class
* extends Application and the launcher is available and abort with an
* error if it's not.
* Set the launch params according to what was passed to LauncherHelper
* so we can use the same launch mode for FX. Abort if there is any
* issue with loading the FX runtime or with the launcher method.
*/
private static Class<?> getFXMainClass(Class<?> mainClass) {
// Check if mainClass extends Application
if (!doesExtendFXApplication(mainClass)) {
return null;
}
private static void setFXLaunchParameters(String what, int mode) {
// Check for the FX launcher classes
try {
fxLauncherClass = scloader.loadClass(JAVAFX_LAUNCHER_CLASS_NAME);
/*
* signature must be:
* public static void launchApplication(String launchName,
* String launchMode, String[] args);
*/
fxLauncherMethod = fxLauncherClass.getMethod("launchApplication",
Class.class, String[].class);
String.class, String.class, String[].class);
// verify launcher signature as we do when validating the main method
int mod = fxLauncherMethod.getModifiers();
if (!Modifier.isStatic(mod)) {
abort(null, "java.launcher.javafx.error1");
}
if (fxLauncherMethod.getReturnType() != java.lang.Void.TYPE) {
abort(null, "java.launcher.javafx.error1");
}
} catch (ClassNotFoundException | NoSuchMethodException ex) {
abort(ex, "java.launcher.cls.error5", ex);
}
// That's all, return this class so we can launch later
return FXHelper.class;
fxLaunchName = what;
switch (mode) {
case LM_CLASS:
fxLaunchMode = JAVAFX_LAUNCH_MODE_CLASS;
break;
case LM_JAR:
fxLaunchMode = JAVAFX_LAUNCH_MODE_JAR;
break;
default:
// should not have gotten this far...
throw new InternalError(mode + ": Unknown launch mode");
}
}
/*
......@@ -696,11 +741,15 @@ public enum LauncherHelper {
return false;
}
// preloader ?
public static void main(String... args) throws Exception {
if (fxLauncherMethod == null
|| fxLaunchMode == null
|| fxLaunchName == null) {
throw new RuntimeException("Invalid JavaFX launch parameters");
}
// launch appClass via fxLauncherMethod
fxLauncherMethod.invoke(null, new Object[] {appClass, args});
fxLauncherMethod.invoke(null,
new Object[] {fxLaunchName, fxLaunchMode, args});
}
}
}
......@@ -140,3 +140,6 @@ java.launcher.jar.error1=\
java.launcher.jar.error2=manifest not found in {0}
java.launcher.jar.error3=no main manifest attribute, in {0}
java.launcher.init.error=initialization error
java.launcher.javafx.error1=\
Error: The JavaFX launchApplication method has the wrong signature, it\n\
must be declared static and return a value of type void
......@@ -206,7 +206,8 @@ public class AuthenticationHeader {
if(v == null) {
if ((v=schemes.get ("digest")) == null) {
if (((v=schemes.get("ntlm"))==null)) {
if (!NTLMAuthenticationProxy.supported
|| ((v=schemes.get("ntlm"))==null)) {
v = schemes.get ("basic");
}
}
......
......@@ -86,7 +86,7 @@ class InitSecContextToken extends InitialToken {
* For the context acceptor to call. It reads the bytes out of an
* InputStream and constructs an InitSecContextToken with them.
*/
InitSecContextToken(Krb5Context context, EncryptionKey[] keys,
InitSecContextToken(Krb5Context context, Krb5AcceptCredential cred,
InputStream is)
throws IOException, GSSException, KrbException {
......@@ -105,7 +105,7 @@ class InitSecContextToken extends InitialToken {
if (context.getChannelBinding() != null) {
addr = context.getChannelBinding().getInitiatorAddress();
}
apReq = new KrbApReq(apReqBytes, keys, addr);
apReq = new KrbApReq(apReqBytes, cred, addr);
//debug("\nReceived AP-REQ and authenticated it.\n");
EncryptionKey sessionKey = apReq.getCreds().getSessionKey();
......
......@@ -45,13 +45,10 @@ import javax.security.auth.DestroyFailedException;
public class Krb5AcceptCredential
implements Krb5CredElement {
private static final long serialVersionUID = 7714332137352567952L;
private final Krb5NameElement name;
private final ServiceCreds screds;
private Krb5NameElement name;
private Krb5Util.ServiceCreds screds;
private Krb5AcceptCredential(Krb5NameElement name, Krb5Util.ServiceCreds creds) {
private Krb5AcceptCredential(Krb5NameElement name, ServiceCreds creds) {
/*
* Initialize this instance with the data from the acquired
* KerberosKey. This class needs to be a KerberosKey too
......@@ -69,11 +66,11 @@ public class Krb5AcceptCredential
name.getKrb5PrincipalName().getName());
final AccessControlContext acc = AccessController.getContext();
Krb5Util.ServiceCreds creds = null;
ServiceCreds creds = null;
try {
creds = AccessController.doPrivileged(
new PrivilegedExceptionAction<Krb5Util.ServiceCreds>() {
public Krb5Util.ServiceCreds run() throws Exception {
new PrivilegedExceptionAction<ServiceCreds>() {
public ServiceCreds run() throws Exception {
return Krb5Util.getServiceCreds(
caller == GSSCaller.CALLER_UNKNOWN ? GSSCaller.CALLER_ACCEPT: caller,
serverPrinc, acc);
......@@ -92,8 +89,10 @@ public class Krb5AcceptCredential
if (name == null) {
String fullName = creds.getName();
name = Krb5NameElement.getInstance(fullName,
if (fullName != null) {
name = Krb5NameElement.getInstance(fullName,
Krb5MechFactory.NT_GSS_KRB5_PRINCIPAL);
}
}
return new Krb5AcceptCredential(name, creds);
......@@ -153,8 +152,8 @@ public class Krb5AcceptCredential
return Krb5MechFactory.PROVIDER;
}
EncryptionKey[] getKrb5EncryptionKeys() {
return screds.getEKeys();
public EncryptionKey[] getKrb5EncryptionKeys(PrincipalName princ) {
return screds.getEKeys(princ);
}
/**
......
......@@ -818,16 +818,23 @@ class Krb5Context implements GSSContextSpi {
}
myName = (Krb5NameElement) myCred.getName();
checkPermission(myName.getKrb5PrincipalName().getName(),
"accept");
EncryptionKey[] secretKeys =
((Krb5AcceptCredential) myCred).getKrb5EncryptionKeys();
// If there is already a bound name, check now
if (myName != null) {
Krb5MechFactory.checkAcceptCredPermission(myName, myName);
}
InitSecContextToken token = new InitSecContextToken(this,
secretKeys, is);
(Krb5AcceptCredential) myCred, is);
PrincipalName clientName = token.getKrbApReq().getClient();
peerName = Krb5NameElement.getInstance(clientName);
// If unbound, check after the bound name is found
if (myName == null) {
myName = Krb5NameElement.getInstance(
token.getKrbApReq().getCreds().getServer());
Krb5MechFactory.checkAcceptCredPermission(myName, myName);
}
if (getMutualAuthState()) {
retVal = new AcceptSecContextToken(this,
token.getKrbApReq()).encode();
......
......@@ -158,7 +158,7 @@ public final class Krb5MechFactory implements MechanismFactory {
public static void checkAcceptCredPermission(Krb5NameElement name,
GSSNameSpi originalName) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
if (sm != null && name != null) {
ServicePermission perm = new ServicePermission
(name.getKrb5PrincipalName().getName(), "accept");
try {
......
......@@ -186,114 +186,6 @@ public class Krb5Util {
return subject;
}
/**
* Credentials of a service, the private secret to authenticate its
* identity, which can be:
* 1. Some KerberosKeys (generated from password)
* 2. A KeyTab (for a typical service)
* 3. A TGT (for S4U2proxy extension)
*
* Note that some creds can coexist. For example, a user2user service
* can use its keytab (or keys) if the client can successfully obtain a
* normal service ticket, otherwise, it can uses the TGT (actually, the
* session key of the TGT) if the client can only acquire a service ticket
* of ENC-TKT-IN-SKEY style.
*/
public static class ServiceCreds {
private KerberosPrincipal kp;
private List<KeyTab> ktabs;
private List<KerberosKey> kk;
private Subject subj;
private KerberosTicket tgt;
private static ServiceCreds getInstance(
Subject subj, String serverPrincipal) {
ServiceCreds sc = new ServiceCreds();
sc.subj = subj;
for (KerberosPrincipal p: subj.getPrincipals(KerberosPrincipal.class)) {
if (serverPrincipal == null ||
p.getName().equals(serverPrincipal)) {
sc.kp = p;
serverPrincipal = p.getName();
break;
}
}
if (sc.kp == null) {
// Compatibility with old behavior: even when there is no
// KerberosPrincipal, we can find one from KerberosKeys
List<KerberosKey> keys = SubjectComber.findMany(
subj, serverPrincipal, null, KerberosKey.class);
if (!keys.isEmpty()) {
sc.kp = keys.get(0).getPrincipal();
serverPrincipal = sc.kp.getName();
if (DEBUG) {
System.out.println(">>> ServiceCreds: no kp?"
+ " find one from kk: " + serverPrincipal);
}
} else {
return null;
}
}
sc.ktabs = SubjectComber.findMany(
subj, null, null, KeyTab.class);
sc.kk = SubjectComber.findMany(
subj, serverPrincipal, null, KerberosKey.class);
sc.tgt = SubjectComber.find(
subj, null, serverPrincipal, KerberosTicket.class);
if (sc.ktabs.isEmpty() && sc.kk.isEmpty() && sc.tgt == null) {
return null;
}
return sc;
}
public String getName() {
return kp.getName();
}
public KerberosKey[] getKKeys() {
List<KerberosKey> keys = new ArrayList<>();
for (KerberosKey k: kk) {
keys.add(k);
}
for (KeyTab ktab: ktabs) {
for (KerberosKey k: ktab.getKeys(kp)) {
keys.add(k);
}
}
return keys.toArray(new KerberosKey[keys.size()]);
}
public EncryptionKey[] getEKeys() {
KerberosKey[] kkeys = getKKeys();
EncryptionKey[] ekeys = new EncryptionKey[kkeys.length];
for (int i=0; i<ekeys.length; i++) {
ekeys[i] = new EncryptionKey(
kkeys[i].getEncoded(), kkeys[i].getKeyType(),
new Integer(kkeys[i].getVersionNumber()));
}
return ekeys;
}
public Credentials getInitCred() {
if (tgt == null) {
return null;
}
try {
return ticketToCreds(tgt);
} catch (KrbException | IOException e) {
return null;
}
}
public void destroy() {
kp = null;
ktabs = null;
kk = null;
tgt = null;
}
}
/**
* Retrieves the ServiceCreds for the specified server principal from
* the Subject in the specified AccessControlContext. If not found, and if
......@@ -361,5 +253,4 @@ public class Krb5Util {
return KerberosSecrets.getJavaxSecurityAuthKerberosAccess().
keyTabGetEncryptionKeys(ktab, cname);
}
}
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.jgss.krb5;
import javax.security.auth.kerberos.KerberosTicket;
import javax.security.auth.kerberos.KerberosKey;
import javax.security.auth.kerberos.KerberosPrincipal;
import javax.security.auth.kerberos.KeyTab;
import javax.security.auth.Subject;
import sun.security.krb5.Credentials;
import sun.security.krb5.EncryptionKey;
import sun.security.krb5.KrbException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import sun.security.krb5.*;
import sun.security.krb5.internal.Krb5;
/**
* Credentials of a kerberos acceptor. A KerberosPrincipal object (kp) is
* the principal. It can be specified as the serverPrincipal argument
* in the getInstance() method, or uses only KerberosPrincipal in the subject.
* Otherwise, the creds object is unbound and kp is null.
*
* The class also encapsulates various secrets, which can be:
*
* 1. Some KerberosKeys (generated from password)
* 2. Some KeyTabs (for a typical service based on keytabs)
* 3. A TGT (for S4U2proxy extension or user2user)
*
* Note that some secrets can coexist. For example, a user2user service
* can use its keytab (or keys) if the client can successfully obtain a
* normal service ticket, or it can use the TGT (actually, the session key
* of the TGT) if the client can only acquire a service ticket
* of ENC-TKT-IN-SKEY style.
*
* @since 1.8
*/
public final class ServiceCreds {
// The principal, or null if unbound
private KerberosPrincipal kp;
// All principals in the subject's princ set
private Set<KerberosPrincipal> allPrincs;
// All private credentials that can be used
private List<KeyTab> ktabs;
private List<KerberosKey> kk;
private KerberosTicket tgt;
private boolean destroyed;
private ServiceCreds() {
// Make sure this class cannot be instantiated externally.
}
/**
* Creates a ServiceCreds object based on info in a Subject for
* a given principal name (if specified).
* @return the object, or null if there is no private creds for it
*/
public static ServiceCreds getInstance(
Subject subj, String serverPrincipal) {
ServiceCreds sc = new ServiceCreds();
sc.allPrincs =
subj.getPrincipals(KerberosPrincipal.class);
// Compatibility. A key implies its own principal
for (KerberosKey key: SubjectComber.findMany(
subj, serverPrincipal, null, KerberosKey.class)) {
sc.allPrincs.add(key.getPrincipal());
}
if (serverPrincipal != null) { // A named principal
sc.kp = new KerberosPrincipal(serverPrincipal);
} else {
if (sc.allPrincs.size() == 1) { // choose the only one
sc.kp = sc.allPrincs.iterator().next();
serverPrincipal = sc.kp.getName();
}
}
sc.ktabs = SubjectComber.findMany(
subj, serverPrincipal, null, KeyTab.class);
sc.kk = SubjectComber.findMany(
subj, serverPrincipal, null, KerberosKey.class);
sc.tgt = SubjectComber.find(
subj, null, serverPrincipal, KerberosTicket.class);
if (sc.ktabs.isEmpty() && sc.kk.isEmpty() && sc.tgt == null) {
return null;
}
sc.destroyed = false;
return sc;
}
// can be null
public String getName() {
if (destroyed) {
throw new IllegalStateException("This object is destroyed");
}
return kp == null ? null : kp.getName();
}
/**
* Gets keys for someone unknown.
* Used by TLS or as a fallback in getEKeys(). Can still return an
* empty array.
*/
public KerberosKey[] getKKeys() {
if (destroyed) {
throw new IllegalStateException("This object is destroyed");
}
if (kp != null) {
return getKKeys(kp);
} else if (!allPrincs.isEmpty()) {
return getKKeys(allPrincs.iterator().next());
}
return new KerberosKey[0];
}
/**
* Get kkeys for a principal,
* @param princ the target name initiator requests. Not null.
* @return keys for the princ, never null, might be empty
*/
private KerberosKey[] getKKeys(KerberosPrincipal princ) {
ArrayList<KerberosKey> keys = new ArrayList<>();
if (kp != null && !princ.equals(kp)) {
return new KerberosKey[0]; // Not me
}
if (!allPrincs.contains(princ)) {
return new KerberosKey[0]; // Not someone I know, This check
// is necessary but a KeyTab has
// no principal name recorded.
}
for (KerberosKey k: kk) {
if (k.getPrincipal().equals(princ)) {
keys.add(k);
}
}
for (KeyTab ktab: ktabs) {
for (KerberosKey k: ktab.getKeys(princ)) {
keys.add(k);
}
}
return keys.toArray(new KerberosKey[keys.size()]);
}
/**
* Gets EKeys for a principal.
* @param princ the target name initiator requests. Not null.
* @return keys for the princ, never null, might be empty
*/
public EncryptionKey[] getEKeys(PrincipalName princ) {
if (destroyed) {
throw new IllegalStateException("This object is destroyed");
}
KerberosKey[] kkeys = getKKeys(new KerberosPrincipal(princ.getName()));
if (kkeys.length == 0) {
// Note: old JDK does not perform real name checking. If the
// acceptor starts by name A but initiator requests for B,
// as long as their keys match (i.e. A's keys can decrypt B's
// service ticket), the authentication is OK. There are real
// customers depending on this to use different names for a
// single service.
kkeys = getKKeys();
}
EncryptionKey[] ekeys = new EncryptionKey[kkeys.length];
for (int i=0; i<ekeys.length; i++) {
ekeys[i] = new EncryptionKey(
kkeys[i].getEncoded(), kkeys[i].getKeyType(),
new Integer(kkeys[i].getVersionNumber()));
}
return ekeys;
}
public Credentials getInitCred() {
if (destroyed) {
throw new IllegalStateException("This object is destroyed");
}
if (tgt == null) {
return null;
}
try {
return Krb5Util.ticketToCreds(tgt);
} catch (KrbException | IOException e) {
return null;
}
}
public void destroy() {
// Do not wipe out real keys because they are references to the
// priv creds in subject. Just make it useless.
destroyed = true;
kp = null;
ktabs.clear();
kk.clear();
tgt = null;
}
}
......@@ -33,6 +33,7 @@ import java.util.Iterator;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.security.auth.kerberos.KerberosPrincipal;
import javax.security.auth.kerberos.KeyTab;
/**
......@@ -84,19 +85,37 @@ class SubjectComber {
} else {
List<T> answer = (oneOnly ? null : new ArrayList<T>());
if (credClass == KeyTab.class) { // Principal un-related
// We are looking for credentials unrelated to serverPrincipal
Iterator<T> iterator =
subject.getPrivateCredentials(credClass).iterator();
while (iterator.hasNext()) {
T t = iterator.next();
if (DEBUG) {
System.out.println("Found " + credClass.getSimpleName());
if (credClass == KeyTab.class) {
// TODO: There is currently no good way to filter out keytabs
// not for serverPrincipal. We can only check the principal
// set. If the server is not there, we can be sure none of the
// keytabs should be used, otherwise, use all for safety.
boolean useAll = false;
if (serverPrincipal != null) {
for (KerberosPrincipal princ:
subject.getPrincipals(KerberosPrincipal.class)) {
if (princ.getName().equals(serverPrincipal)) {
useAll = true;
break;
}
}
if (oneOnly) {
return t;
} else {
answer.add(t);
} else {
useAll = true;
}
if (useAll) {
Iterator<KeyTab> iterator =
subject.getPrivateCredentials(KeyTab.class).iterator();
while (iterator.hasNext()) {
KeyTab t = iterator.next();
if (DEBUG) {
System.out.println("Found " + credClass.getSimpleName()
+ " " + t);
}
if (oneOnly) {
return t;
} else {
answer.add(credClass.cast(t));
}
}
}
} else if (credClass == KerberosKey.class) {
......@@ -114,11 +133,6 @@ class SubjectComber {
if (oneOnly) {
return t;
} else {
if (serverPrincipal == null) {
// Record name so that keys returned will all
// belong to the same principal
serverPrincipal = name;
}
answer.add(credClass.cast(t));
}
}
......
......@@ -34,6 +34,7 @@ package sun.security.krb5;
import sun.security.krb5.internal.*;
import sun.security.krb5.internal.crypto.*;
import sun.security.krb5.internal.rcache.*;
import sun.security.jgss.krb5.Krb5AcceptCredential;
import java.net.InetAddress;
import sun.security.util.*;
import java.io.IOException;
......@@ -135,13 +136,13 @@ public class KrbApReq {
*/
// Used in InitSecContextToken (for AP_REQ and not TGS REQ)
public KrbApReq(byte[] message,
EncryptionKey[] keys,
Krb5AcceptCredential cred,
InetAddress initiator)
throws KrbException, IOException {
obuf = message;
if (apReqMessg == null)
decode();
authenticate(keys, initiator);
authenticate(cred, initiator);
}
/**
......@@ -260,10 +261,11 @@ public class KrbApReq {
}
}
private void authenticate(EncryptionKey[] keys, InetAddress initiator)
private void authenticate(Krb5AcceptCredential cred, InetAddress initiator)
throws KrbException, IOException {
int encPartKeyType = apReqMessg.ticket.encPart.getEType();
Integer kvno = apReqMessg.ticket.encPart.getKeyVersionNumber();
EncryptionKey[] keys = cred.getKrb5EncryptionKeys(apReqMessg.ticket.sname);
EncryptionKey dkey = EncryptionKey.findKey(encPartKeyType, kvno, keys);
if (dkey == null) {
......
......@@ -382,9 +382,15 @@ public class KeyTab implements KeyTabConstants {
*/
public void addEntry(PrincipalName service, char[] psswd,
int kvno, boolean append) throws KrbException {
addEntry(service, service.getSalt(), psswd, kvno, append);
}
// Called by KDC test
public void addEntry(PrincipalName service, String salt, char[] psswd,
int kvno, boolean append) throws KrbException {
EncryptionKey[] encKeys = EncryptionKey.acquireSecretKeys(
psswd, service.getSalt());
psswd, salt);
// There should be only one maximum KVNO value for all etypes, so that
// all added keys can have the same KVNO.
......
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -29,16 +29,17 @@ import java.io.*;
import java.lang.RuntimePermission;
import java.net.SocketPermission;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.security.Principal;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.Vector;
import java.util.StringTokenizer;
import java.text.MessageFormat;
import javax.security.auth.x500.X500Principal;
import java.security.GeneralSecurityException;
import sun.security.util.Debug;
import sun.security.util.PropertyExpander;
import sun.security.util.ResourcesMgr;
......@@ -72,7 +73,7 @@ import sun.security.util.ResourcesMgr;
* Permissions perms = policy.getPermissions(protectiondomain)
* </pre>
*
* <p>The protection domain contains CodeSource
* <p>The protection domain contains a CodeSource
* object, which encapsulates its codebase (URL) and public key attributes.
* It also contains the principals associated with the domain.
* The Policy object evaluates the global policy in light of who the
......@@ -87,9 +88,6 @@ import sun.security.util.ResourcesMgr;
public class PolicyParser {
// needs to be public for PolicyTool
public static final String REPLACE_NAME = "PolicyParser.REPLACE_NAME";
private static final String EXTDIRS_PROPERTY = "java.ext.dirs";
private static final String OLD_EXTDIRS_EXPANSION =
"${" + EXTDIRS_PROPERTY + "}";
......@@ -452,7 +450,7 @@ public class PolicyParser {
peekAndMatch(",");
} else if (peekAndMatch("Principal")) {
if (principals == null) {
principals = new LinkedList<PrincipalEntry>();
principals = new LinkedList<>();
}
String principalClass;
......@@ -461,7 +459,7 @@ public class PolicyParser {
if (peek("\"")) {
// both the principalClass and principalName
// will be replaced later
principalClass = REPLACE_NAME;
principalClass = PrincipalEntry.REPLACE_NAME;
principalName = match("principal type");
} else {
// check for principalClass wildcard
......@@ -916,7 +914,7 @@ public class PolicyParser {
out.print(",\n");
}
if (principals != null && principals.size() > 0) {
ListIterator<PrincipalEntry> pli = principals.listIterator();
Iterator<PrincipalEntry> pli = principals.iterator();
while (pli.hasNext()) {
out.print(" ");
PrincipalEntry pe = pli.next();
......@@ -949,23 +947,22 @@ public class PolicyParser {
/**
* Principal info (class and name) in a grant entry
*/
public static class PrincipalEntry {
public static class PrincipalEntry implements Principal {
public static final String WILDCARD_CLASS = "WILDCARD_PRINCIPAL_CLASS";
public static final String WILDCARD_NAME = "WILDCARD_PRINCIPAL_NAME";
public static final String REPLACE_NAME = "PolicyParser.REPLACE_NAME";
String principalClass;
String principalName;
/**
* A PrincipalEntry consists of the <code>Principal</code>
* class and <code>Principal</code> name.
*
* <p>
*
* @param principalClass the <code>Principal</code> class. <p>
* A PrincipalEntry consists of the Principal class and Principal name.
*
* @param principalName the <code>Principal</code> name. <p>
* @param principalClass the Principal class
* @param principalName the Principal name
* @throws NullPointerException if principalClass or principalName
* are null
*/
public PrincipalEntry(String principalClass, String principalName) {
if (principalClass == null || principalName == null)
......@@ -975,6 +972,18 @@ public class PolicyParser {
this.principalName = principalName;
}
boolean isWildcardName() {
return principalName.equals(WILDCARD_NAME);
}
boolean isWildcardClass() {
return principalClass.equals(WILDCARD_CLASS);
}
boolean isReplaceName() {
return principalClass.equals(REPLACE_NAME);
}
public String getPrincipalClass() {
return principalClass;
}
......@@ -984,9 +993,9 @@ public class PolicyParser {
}
public String getDisplayClass() {
if (principalClass.equals(WILDCARD_CLASS)) {
if (isWildcardClass()) {
return "*";
} else if (principalClass.equals(REPLACE_NAME)) {
} else if (isReplaceName()) {
return "";
}
else return principalClass;
......@@ -997,7 +1006,7 @@ public class PolicyParser {
}
public String getDisplayName(boolean addQuote) {
if (principalName.equals(WILDCARD_NAME)) {
if (isWildcardName()) {
return "*";
}
else {
......@@ -1006,8 +1015,14 @@ public class PolicyParser {
}
}
@Override
public String getName() {
return principalName;
}
@Override
public String toString() {
if (!principalClass.equals(REPLACE_NAME)) {
if (!isReplaceName()) {
return getDisplayClass() + "/" + getDisplayName();
} else {
return getDisplayName();
......@@ -1016,15 +1031,13 @@ public class PolicyParser {
/**
* Test for equality between the specified object and this object.
* Two PrincipalEntries are equal if their PrincipalClass and
* PrincipalName values are equal.
*
* <p>
*
* @param obj the object to test for equality with this object.
* Two PrincipalEntries are equal if their class and name values
* are equal.
*
* @return true if the objects are equal, false otherwise.
* @param obj the object to test for equality with this object
* @return true if the objects are equal, false otherwise
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
......@@ -1033,27 +1046,23 @@ public class PolicyParser {
return false;
PrincipalEntry that = (PrincipalEntry)obj;
if (this.principalClass.equals(that.principalClass) &&
this.principalName.equals(that.principalName)) {
return true;
}
return false;
return (principalClass.equals(that.principalClass) &&
principalName.equals(that.principalName));
}
/**
* Return a hashcode for this <code>PrincipalEntry</code>.
*
* <p>
* Return a hashcode for this PrincipalEntry.
*
* @return a hashcode for this <code>PrincipalEntry</code>.
* @return a hashcode for this PrincipalEntry
*/
@Override
public int hashCode() {
return principalClass.hashCode();
}
public void write(PrintWriter out) {
out.print("principal " + getDisplayClass() + " " +
getDisplayName(true));
getDisplayName(true));
}
}
......@@ -1101,6 +1110,7 @@ public class PolicyParser {
* Calculates a hash code value for the object. Objects
* which are equal will also have the same hashcode.
*/
@Override
public int hashCode() {
int retval = permission.hashCode();
if (name != null) retval ^= name.hashCode();
......@@ -1108,6 +1118,7 @@ public class PolicyParser {
return retval;
}
@Override
public boolean equals(Object obj) {
if (obj == this)
return true;
......@@ -1210,28 +1221,18 @@ public class PolicyParser {
i18nMessage = form.format(source);
}
@Override
public String getLocalizedMessage() {
return i18nMessage;
}
}
public static void main(String arg[]) throws Exception {
FileReader fr = null;
FileWriter fw = null;
try {
try (FileReader fr = new FileReader(arg[0]);
FileWriter fw = new FileWriter(arg[1])) {
PolicyParser pp = new PolicyParser(true);
fr = new FileReader(arg[0]);
pp.read(fr);
fw = new FileWriter(arg[1]);
pp.write(fw);
} finally {
if (fr != null) {
fr.close();
}
if (fw != null) {
fw.close();
}
}
}
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册