提交 f82d7d56 编写于 作者: D dfuchs

Merge

#
# Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
# Copyright 1997-2009 Sun Microsystems, Inc. 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
......@@ -204,6 +204,9 @@ JDI_DOCTITLE = "Java$(TRADEMARK) Debug Interface"
JDI_HEADER = "Java Debug Interface"
# JDI_PKGS is located in NON_CORE_PKGS.gmk
# Variables used by security components
SECURITYAPI_JAVADOCBOTTOM = '<font size="-1"><a href="http://bugs.sun.com/services/bugreport/index.jsp">Report a bug or request a feature.</a><br>Copyright $(THIS_YEAR) Sun Microsystems, Inc. All Rights Reserved. Use is subject to license terms.</font>'
#
# Variables used by JAAS target
#
......@@ -221,6 +224,7 @@ JAAS_JAVADOCFLAGS = $(COMMON_JAVADOCFLAGS) \
-windowtitle $(JAAS_WINDOWTITLE) \
-doctitle $(JAAS_DOCTITLE) \
-header $(JAAS_JAVADOCHEADER) \
-bottom $(SECURITYAPI_JAVADOCBOTTOM) \
-linkoffline ../../../../../api $(DOCSDIR)/api/ \
-overview $(TOPDIR)/src/share/classes/com/sun/security/auth/jaas-overview.html
JAAS_WINDOWTITLE = "Java Authentication and Authorization Service "
......@@ -243,6 +247,7 @@ JGSS_JAVADOCFLAGS = $(COMMON_JAVADOCFLAGS) \
-windowtitle $(JGSS_WINDOWTITLE) \
-doctitle $(JGSS_DOCTITLE) \
-header $(JGSS_JAVADOCHEADER) \
-bottom $(SECURITYAPI_JAVADOCBOTTOM) \
-linkoffline ../../../../../api $(DOCSDIR)/api/ \
-overview $(JGSS_SOURCEPATH)/com/sun/security/jgss/jgss-overview.html
......@@ -266,6 +271,7 @@ SMARTCARDIO_JAVADOCFLAGS = $(COMMON_JAVADOCFLAGS) \
-windowtitle $(SMARTCARDIO_WINDOWTITLE) \
-doctitle $(SMARTCARDIO_DOCTITLE) \
-header $(SMARTCARDIO_JAVADOCHEADER) \
-bottom $(SECURITYAPI_JAVADOCBOTTOM) \
-linkoffline ../../../../../api $(DOCSDIR)/api/
SMARTCARDIO_WINDOWTITLE = "Java Smart Card I/O"
......
......@@ -449,7 +449,6 @@ JAVA_JAVA_java = \
sun/misc/Service.java \
sun/misc/JavaLangAccess.java \
sun/misc/JavaIOAccess.java \
sun/misc/JavaIODeleteOnExitAccess.java \
sun/misc/JavaIOFileDescriptorAccess.java \
sun/misc/JavaNioAccess.java
......
......@@ -503,6 +503,21 @@ public final class Console implements Flushable
// Set up JavaIOAccess in SharedSecrets
static {
// Add a shutdown hook to restore console's echo state should
// it be necessary.
sun.misc.SharedSecrets.getJavaLangAccess()
.registerShutdownHook(0 /* shutdown hook invocation order */,
new Runnable() {
public void run() {
try {
if (echoOff) {
echo(true);
}
} catch (IOException x) { }
}
});
sun.misc.SharedSecrets.setJavaIOAccess(new sun.misc.JavaIOAccess() {
public Console console() {
if (istty()) {
......@@ -513,20 +528,6 @@ public final class Console implements Flushable
return null;
}
// Add a shutdown hook to restore console's echo state should
// it be necessary.
public Runnable consoleRestoreHook() {
return new Runnable() {
public void run() {
try {
if (echoOff) {
echo(true);
}
} catch (IOException x) {}
}
};
}
public Charset charset() {
// This method is called in sun.security.util.Password,
// cons already exists when this method is called
......
......@@ -34,17 +34,18 @@ import java.io.File;
*/
class DeleteOnExitHook {
private static DeleteOnExitHook instance = null;
static {
sun.misc.SharedSecrets.getJavaLangAccess()
.registerShutdownHook(2 /* Shutdown hook invocation order */,
new Runnable() {
public void run() {
runHooks();
}
});
}
private static LinkedHashSet<String> files = new LinkedHashSet<String>();
static DeleteOnExitHook hook() {
if (instance == null)
instance = new DeleteOnExitHook();
return instance;
}
private DeleteOnExitHook() {}
static synchronized void add(String file) {
......@@ -54,7 +55,7 @@ class DeleteOnExitHook {
files.add(file);
}
void run() {
static void runHooks() {
LinkedHashSet<String> theFiles;
synchronized (DeleteOnExitHook.class) {
......
......@@ -2147,18 +2147,6 @@ public class File
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = 301077366599181567L;
// Set up JavaIODeleteOnExitAccess in SharedSecrets
// Added here as DeleteOnExitHook is package-private and SharedSecrets cannot easily access it.
static {
sun.misc.SharedSecrets.setJavaIODeleteOnExitAccess(
new sun.misc.JavaIODeleteOnExitAccess() {
public void run() {
DeleteOnExitHook.hook().run();
}
}
);
}
// -- Integration with java.nio.file --
private volatile transient Path filePath;
......
......@@ -34,19 +34,19 @@ import java.util.*;
* @see java.lang.Runtime#removeShutdownHook
*/
class ApplicationShutdownHooks implements Runnable {
private static ApplicationShutdownHooks instance = null;
class ApplicationShutdownHooks {
static {
Shutdown.add(1 /* shutdown hook invocation order */,
new Runnable() {
public void run() {
runHooks();
}
});
}
/* The set of registered hooks */
private static IdentityHashMap<Thread, Thread> hooks = new IdentityHashMap<Thread, Thread>();
static synchronized ApplicationShutdownHooks hook() {
if (instance == null)
instance = new ApplicationShutdownHooks();
return instance;
}
private ApplicationShutdownHooks() {}
/* Add a new shutdown hook. Checks the shutdown state and the hook itself,
......@@ -82,7 +82,7 @@ class ApplicationShutdownHooks implements Runnable {
* to run in. Hooks are run concurrently and this method waits for
* them to finish.
*/
public void run() {
static void runHooks() {
Collection<Thread> threads;
synchronized(ApplicationShutdownHooks.class) {
threads = hooks.keySet();
......
......@@ -25,8 +25,6 @@
package java.lang;
import java.util.ArrayList;
/**
* Package-private utility class containing data structures and logic
......@@ -47,8 +45,13 @@ class Shutdown {
/* Should we run all finalizers upon exit? */
private static boolean runFinalizersOnExit = false;
/* The set of registered, wrapped hooks, or null if there aren't any */
private static ArrayList<Runnable> hooks = new ArrayList<Runnable>();
// The system shutdown hooks are registered with a predefined slot.
// The list of shutdown hooks is as follows:
// (0) Console restore hook
// (1) Application hooks
// (2) DeleteOnExit hook
private static final int MAX_SYSTEM_HOOKS = 10;
private static final Runnable[] hooks = new Runnable[MAX_SYSTEM_HOOKS];
/* The preceding static fields are protected by this lock */
private static class Lock { };
......@@ -68,33 +71,18 @@ class Shutdown {
/* Add a new shutdown hook. Checks the shutdown state and the hook itself,
* but does not do any security checks.
*/
static void add(Runnable hook) {
static void add(int slot, Runnable hook) {
synchronized (lock) {
if (state > RUNNING)
throw new IllegalStateException("Shutdown in progress");
hooks.add(hook);
}
}
if (hooks[slot] != null)
throw new InternalError("Shutdown hook at slot " + slot + " already registered");
/* Remove a previously-registered hook. Like the add method, this method
* does not do any security checks.
*/
static boolean remove(Runnable hook) {
synchronized (lock) {
if (state > RUNNING)
throw new IllegalStateException("Shutdown in progress");
if (hook == null) throw new NullPointerException();
if (hooks == null) {
return false;
} else {
return hooks.remove(hook);
}
hooks[slot] = hook;
}
}
/* Run all registered shutdown hooks
*/
private static void runHooks() {
......@@ -103,7 +91,7 @@ class Shutdown {
*/
for (Runnable hook : hooks) {
try {
hook.run();
if (hook != null) hook.run();
} catch(Throwable t) {
if (t instanceof ThreadDeath) {
ThreadDeath td = (ThreadDeath)t;
......
......@@ -1121,14 +1121,6 @@ public final class System {
// Setup Java signal handlers for HUP, TERM, and INT (where available).
Terminator.setup();
// The order in with the hooks are added here is important as it
// determines the order in which they are run.
// (1)Console restore hook needs to be called first.
// (2)Application hooks must be run before calling deleteOnExitHook.
Shutdown.add(sun.misc.SharedSecrets.getJavaIOAccess().consoleRestoreHook());
Shutdown.add(ApplicationShutdownHooks.hook());
Shutdown.add(sun.misc.SharedSecrets.getJavaIODeleteOnExitAccess());
// Initialize any miscellenous operating system settings that need to be
// set for the class libraries. Currently this is no-op everywhere except
// for Windows where the process-wide error mode is set before the java.io
......@@ -1174,6 +1166,9 @@ public final class System {
public void blockedOn(Thread t, Interruptible b) {
t.blockedOn(b);
}
public void registerShutdownHook(int slot, Runnable r) {
Shutdown.add(slot, r);
}
});
}
......
......@@ -978,15 +978,6 @@ public class FormattedFloatingDecimal{
return new String(result);
}
// This method should only ever be called if this object is constructed
// without Form.DECIMAL_FLOAT because the perThreadBuffer is not large
// enough to handle floating-point numbers of large precision.
public String toJavaFormatString() {
char result[] = (char[])(perThreadBuffer.get());
int i = getChars(result);
return new String(result, 0, i);
}
// returns the exponent before rounding
public int getExponent() {
return decExponent - 1;
......@@ -1157,265 +1148,6 @@ public class FormattedFloatingDecimal{
}
};
// This method should only ever be called if this object is constructed
// without Form.DECIMAL_FLOAT because the perThreadBuffer is not large
// enough to handle floating-point numbers of large precision.
public void appendTo(Appendable buf) {
char result[] = (char[])(perThreadBuffer.get());
int i = getChars(result);
if (buf instanceof StringBuilder)
((StringBuilder) buf).append(result, 0, i);
else if (buf instanceof StringBuffer)
((StringBuffer) buf).append(result, 0, i);
else
assert false;
}
public static FormattedFloatingDecimal
readJavaFormatString( String in ) throws NumberFormatException {
boolean isNegative = false;
boolean signSeen = false;
int decExp;
char c;
parseNumber:
try{
in = in.trim(); // don't fool around with white space.
// throws NullPointerException if null
int l = in.length();
if ( l == 0 ) throw new NumberFormatException("empty String");
int i = 0;
switch ( c = in.charAt( i ) ){
case '-':
isNegative = true;
//FALLTHROUGH
case '+':
i++;
signSeen = true;
}
// Check for NaN and Infinity strings
c = in.charAt(i);
if(c == 'N' || c == 'I') { // possible NaN or infinity
boolean potentialNaN = false;
char targetChars[] = null; // char arrary of "NaN" or "Infinity"
if(c == 'N') {
targetChars = notANumber;
potentialNaN = true;
} else {
targetChars = infinity;
}
// compare Input string to "NaN" or "Infinity"
int j = 0;
while(i < l && j < targetChars.length) {
if(in.charAt(i) == targetChars[j]) {
i++; j++;
}
else // something is amiss, throw exception
break parseNumber;
}
// For the candidate string to be a NaN or infinity,
// all characters in input string and target char[]
// must be matched ==> j must equal targetChars.length
// and i must equal l
if( (j == targetChars.length) && (i == l) ) { // return NaN or infinity
return (potentialNaN ? new FormattedFloatingDecimal(Double.NaN) // NaN has no sign
: new FormattedFloatingDecimal(isNegative?
Double.NEGATIVE_INFINITY:
Double.POSITIVE_INFINITY)) ;
}
else { // something went wrong, throw exception
break parseNumber;
}
} else if (c == '0') { // check for hexadecimal floating-point number
if (l > i+1 ) {
char ch = in.charAt(i+1);
if (ch == 'x' || ch == 'X' ) // possible hex string
return parseHexString(in);
}
} // look for and process decimal floating-point string
char[] digits = new char[ l ];
int nDigits= 0;
boolean decSeen = false;
int decPt = 0;
int nLeadZero = 0;
int nTrailZero= 0;
digitLoop:
while ( i < l ){
switch ( c = in.charAt( i ) ){
case '0':
if ( nDigits > 0 ){
nTrailZero += 1;
} else {
nLeadZero += 1;
}
break; // out of switch.
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
while ( nTrailZero > 0 ){
digits[nDigits++] = '0';
nTrailZero -= 1;
}
digits[nDigits++] = c;
break; // out of switch.
case '.':
if ( decSeen ){
// already saw one ., this is the 2nd.
throw new NumberFormatException("multiple points");
}
decPt = i;
if ( signSeen ){
decPt -= 1;
}
decSeen = true;
break; // out of switch.
default:
break digitLoop;
}
i++;
}
/*
* At this point, we've scanned all the digits and decimal
* point we're going to see. Trim off leading and trailing
* zeros, which will just confuse us later, and adjust
* our initial decimal exponent accordingly.
* To review:
* we have seen i total characters.
* nLeadZero of them were zeros before any other digits.
* nTrailZero of them were zeros after any other digits.
* if ( decSeen ), then a . was seen after decPt characters
* ( including leading zeros which have been discarded )
* nDigits characters were neither lead nor trailing
* zeros, nor point
*/
/*
* special hack: if we saw no non-zero digits, then the
* answer is zero!
* Unfortunately, we feel honor-bound to keep parsing!
*/
if ( nDigits == 0 ){
digits = zero;
nDigits = 1;
if ( nLeadZero == 0 ){
// we saw NO DIGITS AT ALL,
// not even a crummy 0!
// this is not allowed.
break parseNumber; // go throw exception
}
}
/* Our initial exponent is decPt, adjusted by the number of
* discarded zeros. Or, if there was no decPt,
* then its just nDigits adjusted by discarded trailing zeros.
*/
if ( decSeen ){
decExp = decPt - nLeadZero;
} else {
decExp = nDigits+nTrailZero;
}
/*
* Look for 'e' or 'E' and an optionally signed integer.
*/
if ( (i < l) && (((c = in.charAt(i) )=='e') || (c == 'E') ) ){
int expSign = 1;
int expVal = 0;
int reallyBig = Integer.MAX_VALUE / 10;
boolean expOverflow = false;
switch( in.charAt(++i) ){
case '-':
expSign = -1;
//FALLTHROUGH
case '+':
i++;
}
int expAt = i;
expLoop:
while ( i < l ){
if ( expVal >= reallyBig ){
// the next character will cause integer
// overflow.
expOverflow = true;
}
switch ( c = in.charAt(i++) ){
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
expVal = expVal*10 + ( (int)c - (int)'0' );
continue;
default:
i--; // back up.
break expLoop; // stop parsing exponent.
}
}
int expLimit = bigDecimalExponent+nDigits+nTrailZero;
if ( expOverflow || ( expVal > expLimit ) ){
//
// The intent here is to end up with
// infinity or zero, as appropriate.
// The reason for yielding such a small decExponent,
// rather than something intuitive such as
// expSign*Integer.MAX_VALUE, is that this value
// is subject to further manipulation in
// doubleValue() and floatValue(), and I don't want
// it to be able to cause overflow there!
// (The only way we can get into trouble here is for
// really outrageous nDigits+nTrailZero, such as 2 billion. )
//
decExp = expSign*expLimit;
} else {
// this should not overflow, since we tested
// for expVal > (MAX+N), where N >= abs(decExp)
decExp = decExp + expSign*expVal;
}
// if we saw something not a digit ( or end of string )
// after the [Ee][+-], without seeing any digits at all
// this is certainly an error. If we saw some digits,
// but then some trailing garbage, that might be ok.
// so we just fall through in that case.
// HUMBUG
if ( i == expAt )
break parseNumber; // certainly bad
}
/*
* We parsed everything we could.
* If there are leftovers, then this is not good input!
*/
if ( i < l &&
((i != l - 1) ||
(in.charAt(i) != 'f' &&
in.charAt(i) != 'F' &&
in.charAt(i) != 'd' &&
in.charAt(i) != 'D'))) {
break parseNumber; // go throw exception
}
return new FormattedFloatingDecimal( isNegative, decExp, digits, nDigits, false, Integer.MAX_VALUE, Form.COMPATIBLE );
} catch ( StringIndexOutOfBoundsException e ){ }
throw new NumberFormatException("For input string: \"" + in + "\"");
}
/*
* Take a FormattedFloatingDecimal, which we presumably just scanned in,
* and find out what its value is, as a double.
......@@ -2035,548 +1767,4 @@ public class FormattedFloatingDecimal{
private static final char infinity[] = { 'I', 'n', 'f', 'i', 'n', 'i', 't', 'y' };
private static final char notANumber[] = { 'N', 'a', 'N' };
private static final char zero[] = { '0', '0', '0', '0', '0', '0', '0', '0' };
/*
* Grammar is compatible with hexadecimal floating-point constants
* described in section 6.4.4.2 of the C99 specification.
*/
private static Pattern hexFloatPattern = Pattern.compile(
//1 234 56 7 8 9
"([-+])?0[xX](((\\p{XDigit}+)\\.?)|((\\p{XDigit}*)\\.(\\p{XDigit}+)))[pP]([-+])?(\\p{Digit}+)[fFdD]?"
);
/*
* Convert string s to a suitable floating decimal; uses the
* double constructor and set the roundDir variable appropriately
* in case the value is later converted to a float.
*/
static FormattedFloatingDecimal parseHexString(String s) {
// Verify string is a member of the hexadecimal floating-point
// string language.
Matcher m = hexFloatPattern.matcher(s);
boolean validInput = m.matches();
if (!validInput) {
// Input does not match pattern
throw new NumberFormatException("For input string: \"" + s + "\"");
} else { // validInput
/*
* We must isolate the sign, significand, and exponent
* fields. The sign value is straightforward. Since
* floating-point numbers are stored with a normalized
* representation, the significand and exponent are
* interrelated.
*
* After extracting the sign, we normalized the
* significand as a hexadecimal value, calculating an
* exponent adjust for any shifts made during
* normalization. If the significand is zero, the
* exponent doesn't need to be examined since the output
* will be zero.
*
* Next the exponent in the input string is extracted.
* Afterwards, the significand is normalized as a *binary*
* value and the input value's normalized exponent can be
* computed. The significand bits are copied into a
* double significand; if the string has more logical bits
* than can fit in a double, the extra bits affect the
* round and sticky bits which are used to round the final
* value.
*/
// Extract significand sign
String group1 = m.group(1);
double sign = (( group1 == null ) || group1.equals("+"))? 1.0 : -1.0;
// Extract Significand magnitude
/*
* Based on the form of the significand, calculate how the
* binary exponent needs to be adjusted to create a
* normalized *hexadecimal* floating-point number; that
* is, a number where there is one nonzero hex digit to
* the left of the (hexa)decimal point. Since we are
* adjusting a binary, not hexadecimal exponent, the
* exponent is adjusted by a multiple of 4.
*
* There are a number of significand scenarios to consider;
* letters are used in indicate nonzero digits:
*
* 1. 000xxxx => x.xxx normalized
* increase exponent by (number of x's - 1)*4
*
* 2. 000xxx.yyyy => x.xxyyyy normalized
* increase exponent by (number of x's - 1)*4
*
* 3. .000yyy => y.yy normalized
* decrease exponent by (number of zeros + 1)*4
*
* 4. 000.00000yyy => y.yy normalized
* decrease exponent by (number of zeros to right of point + 1)*4
*
* If the significand is exactly zero, return a properly
* signed zero.
*/
String significandString =null;
int signifLength = 0;
int exponentAdjust = 0;
{
int leftDigits = 0; // number of meaningful digits to
// left of "decimal" point
// (leading zeros stripped)
int rightDigits = 0; // number of digits to right of
// "decimal" point; leading zeros
// must always be accounted for
/*
* The significand is made up of either
*
* 1. group 4 entirely (integer portion only)
*
* OR
*
* 2. the fractional portion from group 7 plus any
* (optional) integer portions from group 6.
*/
String group4;
if( (group4 = m.group(4)) != null) { // Integer-only significand
// Leading zeros never matter on the integer portion
significandString = stripLeadingZeros(group4);
leftDigits = significandString.length();
}
else {
// Group 6 is the optional integer; leading zeros
// never matter on the integer portion
String group6 = stripLeadingZeros(m.group(6));
leftDigits = group6.length();
// fraction
String group7 = m.group(7);
rightDigits = group7.length();
// Turn "integer.fraction" into "integer"+"fraction"
significandString =
((group6 == null)?"":group6) + // is the null
// check necessary?
group7;
}
significandString = stripLeadingZeros(significandString);
signifLength = significandString.length();
/*
* Adjust exponent as described above
*/
if (leftDigits >= 1) { // Cases 1 and 2
exponentAdjust = 4*(leftDigits - 1);
} else { // Cases 3 and 4
exponentAdjust = -4*( rightDigits - signifLength + 1);
}
// If the significand is zero, the exponent doesn't
// matter; return a properly signed zero.
if (signifLength == 0) { // Only zeros in input
return new FormattedFloatingDecimal(sign * 0.0);
}
}
// Extract Exponent
/*
* Use an int to read in the exponent value; this should
* provide more than sufficient range for non-contrived
* inputs. If reading the exponent in as an int does
* overflow, examine the sign of the exponent and
* significand to determine what to do.
*/
String group8 = m.group(8);
boolean positiveExponent = ( group8 == null ) || group8.equals("+");
long unsignedRawExponent;
try {
unsignedRawExponent = Integer.parseInt(m.group(9));
}
catch (NumberFormatException e) {
// At this point, we know the exponent is
// syntactically well-formed as a sequence of
// digits. Therefore, if an NumberFormatException
// is thrown, it must be due to overflowing int's
// range. Also, at this point, we have already
// checked for a zero significand. Thus the signs
// of the exponent and significand determine the
// final result:
//
// significand
// + -
// exponent + +infinity -infinity
// - +0.0 -0.0
return new FormattedFloatingDecimal(sign * (positiveExponent ?
Double.POSITIVE_INFINITY : 0.0));
}
long rawExponent =
(positiveExponent ? 1L : -1L) * // exponent sign
unsignedRawExponent; // exponent magnitude
// Calculate partially adjusted exponent
long exponent = rawExponent + exponentAdjust ;
// Starting copying non-zero bits into proper position in
// a long; copy explicit bit too; this will be masked
// later for normal values.
boolean round = false;
boolean sticky = false;
int bitsCopied=0;
int nextShift=0;
long significand=0L;
// First iteration is different, since we only copy
// from the leading significand bit; one more exponent
// adjust will be needed...
// IMPORTANT: make leadingDigit a long to avoid
// surprising shift semantics!
long leadingDigit = getHexDigit(significandString, 0);
/*
* Left shift the leading digit (53 - (bit position of
* leading 1 in digit)); this sets the top bit of the
* significand to 1. The nextShift value is adjusted
* to take into account the number of bit positions of
* the leadingDigit actually used. Finally, the
* exponent is adjusted to normalize the significand
* as a binary value, not just a hex value.
*/
if (leadingDigit == 1) {
significand |= leadingDigit << 52;
nextShift = 52 - 4;
/* exponent += 0 */ }
else if (leadingDigit <= 3) { // [2, 3]
significand |= leadingDigit << 51;
nextShift = 52 - 5;
exponent += 1;
}
else if (leadingDigit <= 7) { // [4, 7]
significand |= leadingDigit << 50;
nextShift = 52 - 6;
exponent += 2;
}
else if (leadingDigit <= 15) { // [8, f]
significand |= leadingDigit << 49;
nextShift = 52 - 7;
exponent += 3;
} else {
throw new AssertionError("Result from digit converstion too large!");
}
// The preceding if-else could be replaced by a single
// code block based on the high-order bit set in
// leadingDigit. Given leadingOnePosition,
// significand |= leadingDigit << (SIGNIFICAND_WIDTH - leadingOnePosition);
// nextShift = 52 - (3 + leadingOnePosition);
// exponent += (leadingOnePosition-1);
/*
* Now the exponent variable is equal to the normalized
* binary exponent. Code below will make representation
* adjustments if the exponent is incremented after
* rounding (includes overflows to infinity) or if the
* result is subnormal.
*/
// Copy digit into significand until the significand can't
// hold another full hex digit or there are no more input
// hex digits.
int i = 0;
for(i = 1;
i < signifLength && nextShift >= 0;
i++) {
long currentDigit = getHexDigit(significandString, i);
significand |= (currentDigit << nextShift);
nextShift-=4;
}
// After the above loop, the bulk of the string is copied.
// Now, we must copy any partial hex digits into the
// significand AND compute the round bit and start computing
// sticky bit.
if ( i < signifLength ) { // at least one hex input digit exists
long currentDigit = getHexDigit(significandString, i);
// from nextShift, figure out how many bits need
// to be copied, if any
switch(nextShift) { // must be negative
case -1:
// three bits need to be copied in; can
// set round bit
significand |= ((currentDigit & 0xEL) >> 1);
round = (currentDigit & 0x1L) != 0L;
break;
case -2:
// two bits need to be copied in; can
// set round and start sticky
significand |= ((currentDigit & 0xCL) >> 2);
round = (currentDigit &0x2L) != 0L;
sticky = (currentDigit & 0x1L) != 0;
break;
case -3:
// one bit needs to be copied in
significand |= ((currentDigit & 0x8L)>>3);
// Now set round and start sticky, if possible
round = (currentDigit &0x4L) != 0L;
sticky = (currentDigit & 0x3L) != 0;
break;
case -4:
// all bits copied into significand; set
// round and start sticky
round = ((currentDigit & 0x8L) != 0); // is top bit set?
// nonzeros in three low order bits?
sticky = (currentDigit & 0x7L) != 0;
break;
default:
throw new AssertionError("Unexpected shift distance remainder.");
// break;
}
// Round is set; sticky might be set.
// For the sticky bit, it suffices to check the
// current digit and test for any nonzero digits in
// the remaining unprocessed input.
i++;
while(i < signifLength && !sticky) {
currentDigit = getHexDigit(significandString,i);
sticky = sticky || (currentDigit != 0);
i++;
}
}
// else all of string was seen, round and sticky are
// correct as false.
// Check for overflow and update exponent accordingly.
if (exponent > DoubleConsts.MAX_EXPONENT) { // Infinite result
// overflow to properly signed infinity
return new FormattedFloatingDecimal(sign * Double.POSITIVE_INFINITY);
} else { // Finite return value
if (exponent <= DoubleConsts.MAX_EXPONENT && // (Usually) normal result
exponent >= DoubleConsts.MIN_EXPONENT) {
// The result returned in this block cannot be a
// zero or subnormal; however after the
// significand is adjusted from rounding, we could
// still overflow in infinity.
// AND exponent bits into significand; if the
// significand is incremented and overflows from
// rounding, this combination will update the
// exponent correctly, even in the case of
// Double.MAX_VALUE overflowing to infinity.
significand = (( ((long)exponent +
(long)DoubleConsts.EXP_BIAS) <<
(DoubleConsts.SIGNIFICAND_WIDTH-1))
& DoubleConsts.EXP_BIT_MASK) |
(DoubleConsts.SIGNIF_BIT_MASK & significand);
} else { // Subnormal or zero
// (exponent < DoubleConsts.MIN_EXPONENT)
if (exponent < (DoubleConsts.MIN_SUB_EXPONENT -1 )) {
// No way to round back to nonzero value
// regardless of significand if the exponent is
// less than -1075.
return new FormattedFloatingDecimal(sign * 0.0);
} else { // -1075 <= exponent <= MIN_EXPONENT -1 = -1023
/*
* Find bit position to round to; recompute
* round and sticky bits, and shift
* significand right appropriately.
*/
sticky = sticky || round;
round = false;
// Number of bits of significand to preserve is
// exponent - abs_min_exp +1
// check:
// -1075 +1074 + 1 = 0
// -1023 +1074 + 1 = 52
int bitsDiscarded = 53 -
((int)exponent - DoubleConsts.MIN_SUB_EXPONENT + 1);
assert bitsDiscarded >= 1 && bitsDiscarded <= 53;
// What to do here:
// First, isolate the new round bit
round = (significand & (1L << (bitsDiscarded -1))) != 0L;
if (bitsDiscarded > 1) {
// create mask to update sticky bits; low
// order bitsDiscarded bits should be 1
long mask = ~((~0L) << (bitsDiscarded -1));
sticky = sticky || ((significand & mask) != 0L ) ;
}
// Now, discard the bits
significand = significand >> bitsDiscarded;
significand = (( ((long)(DoubleConsts.MIN_EXPONENT -1) + // subnorm exp.
(long)DoubleConsts.EXP_BIAS) <<
(DoubleConsts.SIGNIFICAND_WIDTH-1))
& DoubleConsts.EXP_BIT_MASK) |
(DoubleConsts.SIGNIF_BIT_MASK & significand);
}
}
// The significand variable now contains the currently
// appropriate exponent bits too.
/*
* Determine if significand should be incremented;
* making this determination depends on the least
* significant bit and the round and sticky bits.
*
* Round to nearest even rounding table, adapted from
* table 4.7 in "Computer Arithmetic" by IsraelKoren.
* The digit to the left of the "decimal" point is the
* least significant bit, the digits to the right of
* the point are the round and sticky bits
*
* Number Round(x)
* x0.00 x0.
* x0.01 x0.
* x0.10 x0.
* x0.11 x1. = x0. +1
* x1.00 x1.
* x1.01 x1.
* x1.10 x1. + 1
* x1.11 x1. + 1
*/
boolean incremented = false;
boolean leastZero = ((significand & 1L) == 0L);
if( ( leastZero && round && sticky ) ||
((!leastZero) && round )) {
incremented = true;
significand++;
}
FormattedFloatingDecimal fd = new FormattedFloatingDecimal(FpUtils.rawCopySign(
Double.longBitsToDouble(significand),
sign));
/*
* Set roundingDir variable field of fd properly so
* that the input string can be properly rounded to a
* float value. There are two cases to consider:
*
* 1. rounding to double discards sticky bit
* information that would change the result of a float
* rounding (near halfway case between two floats)
*
* 2. rounding to double rounds up when rounding up
* would not occur when rounding to float.
*
* For former case only needs to be considered when
* the bits rounded away when casting to float are all
* zero; otherwise, float round bit is properly set
* and sticky will already be true.
*
* The lower exponent bound for the code below is the
* minimum (normalized) subnormal exponent - 1 since a
* value with that exponent can round up to the
* minimum subnormal value and the sticky bit
* information must be preserved (i.e. case 1).
*/
if ((exponent >= FloatConsts.MIN_SUB_EXPONENT-1) &&
(exponent <= FloatConsts.MAX_EXPONENT ) ){
// Outside above exponent range, the float value
// will be zero or infinity.
/*
* If the low-order 28 bits of a rounded double
* significand are 0, the double could be a
* half-way case for a rounding to float. If the
* double value is a half-way case, the double
* significand may have to be modified to round
* the the right float value (see the stickyRound
* method). If the rounding to double has lost
* what would be float sticky bit information, the
* double significand must be incremented. If the
* double value's significand was itself
* incremented, the float value may end up too
* large so the increment should be undone.
*/
if ((significand & 0xfffffffL) == 0x0L) {
// For negative values, the sign of the
// roundDir is the same as for positive values
// since adding 1 increasing the significand's
// magnitude and subtracting 1 decreases the
// significand's magnitude. If neither round
// nor sticky is true, the double value is
// exact and no adjustment is required for a
// proper float rounding.
if( round || sticky) {
if (leastZero) { // prerounding lsb is 0
// If round and sticky were both true,
// and the least significant
// significand bit were 0, the rounded
// significand would not have its
// low-order bits be zero. Therefore,
// we only need to adjust the
// significand if round XOR sticky is
// true.
if (round ^ sticky) {
fd.roundDir = 1;
}
}
else { // prerounding lsb is 1
// If the prerounding lsb is 1 and the
// resulting significand has its
// low-order bits zero, the significand
// was incremented. Here, we undo the
// increment, which will ensure the
// right guard and sticky bits for the
// float rounding.
if (round)
fd.roundDir = -1;
}
}
}
}
fd.fromHex = true;
return fd;
}
}
}
/**
* Return <code>s</code> with any leading zeros removed.
*/
static String stripLeadingZeros(String s) {
return s.replaceFirst("^0+", "");
}
/**
* Extract a hexadecimal digit from position <code>position</code>
* of string <code>s</code>.
*/
static int getHexDigit(String s, int position) {
int value = Character.digit(s.charAt(position), 16);
if (value <= -1 || value >= 16) {
throw new AssertionError("Unxpected failure of digit converstion of " +
s.charAt(position));
}
return value;
}
}
......@@ -29,6 +29,5 @@ import java.nio.charset.Charset;
public interface JavaIOAccess {
public Console console();
public Runnable consoleRestoreHook();
public Charset charset();
}
/*
* Copyright 2005 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.misc;
public interface JavaIODeleteOnExitAccess extends Runnable {
public void run();
}
......@@ -54,4 +54,7 @@ public interface JavaLangAccess {
/** Set thread's blocker field. */
void blockedOn(Thread t, Interruptible b);
/** register shutdown hook */
void registerShutdownHook(int slot, Runnable r);
}
......@@ -44,7 +44,6 @@ public class SharedSecrets {
private static JavaUtilJarAccess javaUtilJarAccess;
private static JavaLangAccess javaLangAccess;
private static JavaIOAccess javaIOAccess;
private static JavaIODeleteOnExitAccess javaIODeleteOnExitAccess;
private static JavaNetAccess javaNetAccess;
private static JavaNioAccess javaNioAccess;
private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
......@@ -103,17 +102,6 @@ public class SharedSecrets {
return javaIOAccess;
}
public static void setJavaIODeleteOnExitAccess(JavaIODeleteOnExitAccess jida) {
javaIODeleteOnExitAccess = jida;
}
public static JavaIODeleteOnExitAccess getJavaIODeleteOnExitAccess() {
if (javaIODeleteOnExitAccess == null) {
unsafe.ensureClassInitialized(File.class);
}
return javaIODeleteOnExitAccess;
}
public static void setJavaIOFileDescriptorAccess(JavaIOFileDescriptorAccess jiofda) {
javaIOFileDescriptorAccess = jiofda;
}
......
/*
* Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2005-2009 Sun Microsystems, Inc. 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
......@@ -66,11 +66,11 @@ public class NegTokenInit extends SpNegoToken {
private byte[] mechTypes = null;
private Oid[] mechTypeList = null;
private byte[] reqFlags = null;
private BitArray reqFlags = null;
private byte[] mechToken = null;
private byte[] mechListMIC = null;
NegTokenInit(byte[] mechTypes, byte[] flags,
NegTokenInit(byte[] mechTypes, BitArray flags,
byte[] token, byte[] mechListMIC)
{
super(NEG_TOKEN_INIT_ID);
......@@ -101,7 +101,7 @@ public class NegTokenInit extends SpNegoToken {
// write context flags with CONTEXT 01
if (reqFlags != null) {
DerOutputStream flags = new DerOutputStream();
flags.putBitString(reqFlags);
flags.putUnalignedBitString(reqFlags);
initToken.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x01), flags);
}
......@@ -237,7 +237,7 @@ public class NegTokenInit extends SpNegoToken {
return mechTypeList;
}
byte[] getReqFlags() {
BitArray getReqFlags() {
return reqFlags;
}
......
/*
* Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2005-2009 Sun Microsystems, Inc. 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
......@@ -53,13 +53,6 @@ public class SpNegoContext implements GSSContextSpi {
private int state = STATE_NEW;
private static final int CHECKSUM_DELEG_FLAG = 1;
private static final int CHECKSUM_MUTUAL_FLAG = 2;
private static final int CHECKSUM_REPLAY_FLAG = 4;
private static final int CHECKSUM_SEQUENCE_FLAG = 8;
private static final int CHECKSUM_CONF_FLAG = 16;
private static final int CHECKSUM_INTEG_FLAG = 32;
/*
* Optional features that the application can set and their default
* values.
......@@ -697,25 +690,17 @@ public class SpNegoContext implements GSSContextSpi {
/**
* get the context flags
*/
private byte[] getContextFlags() {
int flags = 0;
if (getCredDelegState())
flags |= CHECKSUM_DELEG_FLAG;
if (getMutualAuthState())
flags |= CHECKSUM_MUTUAL_FLAG;
if (getReplayDetState())
flags |= CHECKSUM_REPLAY_FLAG;
if (getSequenceDetState())
flags |= CHECKSUM_SEQUENCE_FLAG;
if (getIntegState())
flags |= CHECKSUM_INTEG_FLAG;
if (getConfState())
flags |= CHECKSUM_CONF_FLAG;
byte[] temp = new byte[1];
temp[0] = (byte)(flags & 0xff);
return temp;
private BitArray getContextFlags() {
BitArray out = new BitArray(7);
if (getCredDelegState()) out.set(0, true);
if (getMutualAuthState()) out.set(1, true);
if (getReplayDetState()) out.set(2, true);
if (getSequenceDetState()) out.set(3, true);
if (getConfState()) out.set(5, true);
if (getIntegState()) out.set(6, true);
return out;
}
private void setContextFlags() {
......
/*
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -28,8 +28,6 @@ package sun.security.provider.certpath;
import java.io.*;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CRLReason;
import java.security.cert.X509Certificate;
......@@ -335,7 +333,7 @@ class OCSPResponse {
// Check whether the cert returned by the responder is trusted
if (x509Certs != null && x509Certs[0] != null) {
X509Certificate cert = x509Certs[0];
X509CertImpl cert = x509Certs[0];
// First check if the cert matches the responder cert which
// was set locally.
......@@ -344,8 +342,8 @@ class OCSPResponse {
// Next check if the cert was issued by the responder cert
// which was set locally.
} else if (cert.getIssuerDN().equals(
responderCert.getSubjectDN())) {
} else if (cert.getIssuerX500Principal().equals(
responderCert.getSubjectX500Principal())) {
// Check for the OCSPSigning key purpose
List<String> keyPurposes = cert.getExtendedKeyUsage();
......@@ -360,6 +358,43 @@ class OCSPResponse {
"OCSP responses");
}
// check the validity
try {
Date dateCheckedAgainst = params.getDate();
if (dateCheckedAgainst == null) {
cert.checkValidity();
} else {
cert.checkValidity(dateCheckedAgainst);
}
} catch (GeneralSecurityException e) {
if (DEBUG != null) {
DEBUG.println("Responder's certificate is not " +
"within the validity period.");
}
throw new CertPathValidatorException(
"Responder's certificate not within the " +
"validity period");
}
// check for revocation
//
// A CA may specify that an OCSP client can trust a
// responder for the lifetime of the responder's
// certificate. The CA does so by including the
// extension id-pkix-ocsp-nocheck.
//
Extension noCheck =
cert.getExtension(PKIXExtensions.OCSPNoCheck_Id);
if (noCheck != null) {
if (DEBUG != null) {
DEBUG.println("Responder's certificate includes " +
"the extension id-pkix-ocsp-nocheck.");
}
} else {
// we should do the revocating checking of the
// authorized responder in a future update.
}
// verify the signature
try {
cert.verify(responderCert.getPublicKey());
......@@ -369,6 +404,14 @@ class OCSPResponse {
} catch (GeneralSecurityException e) {
responderCert = null;
}
} else {
if (DEBUG != null) {
DEBUG.println("Responder's certificate is not " +
"authorized to sign OCSP responses.");
}
throw new CertPathValidatorException(
"Responder's certificate not authorized to sign " +
"OCSP responses");
}
}
......
/*
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.security.x509;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Enumeration;
import sun.security.util.*;
/**
* Represent the OCSP NoCheck Extension from RFC2560.
* <p>
* A CA may specify that an OCSP client can trust a responder for the
* lifetime of the responder's certificate. The CA does so by including
* the extension id-pkix-ocsp-nocheck. This SHOULD be a non-critical
* extension. The value of the extension should be NULL. CAs issuing
* such a certificate should realized that a compromise of the
* responder's key, is as serious as the compromise of a CA key used to
* sign CRLs, at least for the validity period of this certificate. CA's
* may choose to issue this type of certificate with a very short
* lifetime and renew it frequently.
* <pre>
* id-pkix-ocsp-nocheck OBJECT IDENTIFIER ::= { id-pkix-ocsp 5 }
* </pre>
*
* @author Xuelei Fan
* @see Extension
* @see CertAttrSet
*/
public class OCSPNoCheckExtension extends Extension
implements CertAttrSet<String> {
/**
* Identifier for this attribute, to be used with the
* get, set, delete methods of Certificate, x509 type.
*/
public static final String IDENT =
"x509.info.extensions.OCSPNoCheck";
/**
* Attribute names.
*/
public static final String NAME = "OCSPNoCheck";
/**
* Create a OCSPNoCheckExtension
*/
public OCSPNoCheckExtension() throws IOException {
this.extensionId = PKIXExtensions.OCSPNoCheck_Id;
this.critical = false;
this.extensionValue = new byte[0];
}
/**
* Create the extension from the passed DER encoded value.
*
* @param critical true if the extension is to be treated as critical.
* @param value an array of DER encoded bytes of the actual value.
* @exception IOException on error.
*/
public OCSPNoCheckExtension(Boolean critical, Object value)
throws IOException {
this.extensionId = PKIXExtensions.OCSPNoCheck_Id;
this.critical = critical.booleanValue();
// the value should be null, just ignore it here.
this.extensionValue = new byte[0];
}
/**
* Set the attribute value.
*/
public void set(String name, Object obj) throws IOException {
throw new IOException("No attribute is allowed by " +
"CertAttrSet:OCSPNoCheckExtension.");
}
/**
* Get the attribute value.
*/
public Object get(String name) throws IOException {
throw new IOException("No attribute is allowed by " +
"CertAttrSet:OCSPNoCheckExtension.");
}
/**
* Delete the attribute value.
*/
public void delete(String name) throws IOException {
throw new IOException("No attribute is allowed by " +
"CertAttrSet:OCSPNoCheckExtension.");
}
/**
* Return an enumeration of names of attributes existing within this
* attribute.
*/
public Enumeration<String> getElements() {
return (new AttributeNameEnumeration()).elements();
}
/**
* Return the name of this attribute.
*/
public String getName() {
return NAME;
}
}
......@@ -100,6 +100,8 @@ public class OIDMap {
DeltaCRLIndicatorExtension.NAME;
private static final String FRESHEST_CRL = ROOT + "." +
FreshestCRLExtension.NAME;
private static final String OCSPNOCHECK = ROOT + "." +
OCSPNoCheckExtension.NAME;
private static final int NetscapeCertType_data[] =
{ 2, 16, 840, 1, 113730, 1, 1 };
......@@ -161,6 +163,8 @@ public class OIDMap {
"sun.security.x509.DeltaCRLIndicatorExtension");
addInternal(FRESHEST_CRL, PKIXExtensions.FreshestCRL_Id,
"sun.security.x509.FreshestCRLExtension");
addInternal(OCSPNOCHECK, PKIXExtensions.OCSPNoCheck_Id,
"sun.security.x509.OCSPNoCheckExtension");
}
/**
......
/*
* Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1997-2009 Sun Microsystems, Inc. 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
......@@ -74,6 +74,8 @@ public class PKIXExtensions {
private static final int AuthInfoAccess_data [] = { 1, 3, 6, 1, 5, 5, 7, 1, 1};
private static final int SubjectInfoAccess_data [] = { 1, 3, 6, 1, 5, 5, 7, 1, 11};
private static final int FreshestCRL_data [] = { 2, 5, 29, 46 };
private static final int OCSPNoCheck_data [] = { 1, 3, 6, 1, 5, 5, 7,
48, 1, 5};
/**
* Identifies the particular public key used to sign the certificate.
......@@ -216,6 +218,12 @@ public class PKIXExtensions {
*/
public static final ObjectIdentifier FreshestCRL_Id;
/**
* Identifies the OCSP client can trust the responder for the
* lifetime of the responder's certificate.
*/
public static final ObjectIdentifier OCSPNoCheck_Id;
static {
AuthorityKey_Id = ObjectIdentifier.newInternal(AuthorityKey_data);
SubjectKey_Id = ObjectIdentifier.newInternal(SubjectKey_data);
......@@ -257,5 +265,6 @@ public class PKIXExtensions {
SubjectInfoAccess_Id =
ObjectIdentifier.newInternal(SubjectInfoAccess_data);
FreshestCRL_Id = ObjectIdentifier.newInternal(FreshestCRL_data);
OCSPNoCheck_Id = ObjectIdentifier.newInternal(OCSPNoCheck_data);
}
}
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 6815182
* @summary GSSAPI/SPNEGO does not work with server using MIT Kerberos library
*/
import sun.security.jgss.GSSUtil;
import sun.security.util.BitArray;
import sun.security.util.DerInputStream;
import sun.security.util.DerValue;
public class SpnegoReqFlags {
public static void main(String[] args)
throws Exception {
// Create and start the KDC
new OneKDC(null).writeJAASConf();
new SpnegoReqFlags().go();
}
void go() throws Exception {
Context c = Context.fromJAAS("client");
c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_SPNEGO_MECH_OID);
byte[] token = c.doAs(new Action() {
@Override
public byte[] run(Context me, byte[] input) throws Exception {
me.x().requestCredDeleg(true);
me.x().requestReplayDet(false);
me.x().requestSequenceDet(false);
return me.x().initSecContext(new byte[0], 0, 0);
}
}, null);
DerValue d = new DerValue(token); // GSSToken
DerInputStream ins = d.data; // OID + mech token
d.data.getDerValue(); // skip OID
d = d.data.getDerValue(); // NegTokenInit
d = d.data.getDerValue(); // The SEQUENCE inside
boolean found = false;
// Go through all fields inside NegTokenInit. The reqFlags field
// is optional. It's even not recommended in RFC 4178.
while (d.data.available() > 0) {
DerValue d2 = d.data.getDerValue();
if (d2.isContextSpecific((byte)1)) {
found = true;
System.out.println("regFlags field located.");
BitArray ba = d2.data.getUnalignedBitString();
if (ba.length() != 7) {
throw new Exception("reqFlags should contain 7 bits");
}
if (!ba.get(0)) {
throw new Exception("delegFlag should be true");
}
if (ba.get(2) || ba.get(3)) {
throw new Exception("replay/sequenceFlag should be false");
}
}
}
if (!found) {
System.out.println("Warning: regFlags field not found, too new?");
}
c.dispose();
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册