feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
345
jdkSrc/jdk8/sun/security/jgss/GSSHeader.java
Normal file
345
jdkSrc/jdk8/sun/security/jgss/GSSHeader.java
Normal file
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2006, 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;
|
||||
|
||||
import org.ietf.jgss.GSSException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class represents the mechanism independent part of a GSS-API
|
||||
* context establishment token. Some mechanisms may choose to encode
|
||||
* all subsequent tokens as well such that they start with an encoding
|
||||
* of an instance of this class. e.g., The Kerberos v5 GSS-API Mechanism
|
||||
* uses this header for all GSS-API tokens.
|
||||
* <p>
|
||||
* The format is specified in RFC 2743 section 3.1.
|
||||
*
|
||||
* @author Mayank Upadhyay
|
||||
*/
|
||||
|
||||
/*
|
||||
* The RFC states that implementations should explicitly follow the
|
||||
* encoding scheme descibed in this section rather than use ASN.1
|
||||
* compilers. However, we should consider removing duplicate ASN.1
|
||||
* like code from here and depend on sun.security.util if possible.
|
||||
*/
|
||||
|
||||
public class GSSHeader {
|
||||
|
||||
private ObjectIdentifier mechOid = null;
|
||||
private byte[] mechOidBytes = null;
|
||||
private int mechTokenLength = 0;
|
||||
|
||||
/**
|
||||
* The tag defined in the GSS-API mechanism independent token
|
||||
* format.
|
||||
*/
|
||||
public static final int TOKEN_ID=0x60;
|
||||
|
||||
/**
|
||||
* Creates a GSSHeader instance whose encoding can be used as the
|
||||
* prefix for a particular mechanism token.
|
||||
* @param mechOid the Oid of the mechanism which generated the token
|
||||
* @param mechTokenLength the length of the subsequent portion that
|
||||
* the mechanism will be adding.
|
||||
*/
|
||||
public GSSHeader(ObjectIdentifier mechOid, int mechTokenLength)
|
||||
throws IOException {
|
||||
|
||||
this.mechOid = mechOid;
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
temp.putOID(mechOid);
|
||||
mechOidBytes = temp.toByteArray();
|
||||
this.mechTokenLength = mechTokenLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads in a GSSHeader from an InputStream. Typically this would be
|
||||
* used as part of reading the complete token from an InputStream
|
||||
* that is obtained from a socket.
|
||||
*/
|
||||
public GSSHeader(InputStream is)
|
||||
throws IOException, GSSException {
|
||||
|
||||
// debug("Parsing GSS token: ");
|
||||
|
||||
int tag = is.read();
|
||||
|
||||
// debug("tag=" + tag);
|
||||
|
||||
if (tag != TOKEN_ID)
|
||||
throw new GSSException(GSSException.DEFECTIVE_TOKEN, -1,
|
||||
"GSSHeader did not find the right tag");
|
||||
|
||||
int length = getLength(is);
|
||||
|
||||
DerValue temp = new DerValue(is);
|
||||
mechOidBytes = temp.toByteArray();
|
||||
mechOid = temp.getOID();
|
||||
// debug (" oid=" + mechOid);
|
||||
|
||||
// debug (" len starting with oid=" + length);
|
||||
mechTokenLength = length - mechOidBytes.length;
|
||||
|
||||
// debug(" mechToken length=" + mechTokenLength);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to obtain the Oid stored in this GSSHeader instance.
|
||||
* @return the Oid of the mechanism.
|
||||
*/
|
||||
public ObjectIdentifier getOid() {
|
||||
return mechOid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to obtain the length of the mechanism specific token that
|
||||
* will follow the encoding of this GSSHeader instance.
|
||||
* @return the length of the mechanism specific token portion that
|
||||
* will follow this GSSHeader.
|
||||
*/
|
||||
public int getMechTokenLength() {
|
||||
return mechTokenLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to obtain the length of the encoding of this GSSHeader.
|
||||
* @return the lenght of the encoding of this GSSHeader instance.
|
||||
*/
|
||||
public int getLength() {
|
||||
int lenField = mechOidBytes.length + mechTokenLength;
|
||||
return (1 + getLenFieldSize(lenField) + mechOidBytes.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to determine what the maximum possible mechanism token
|
||||
* size is if the complete GSSToken returned to the application
|
||||
* (including a GSSHeader) is not to exceed some pre-determined
|
||||
* value in size.
|
||||
* @param mechOid the Oid of the mechanism that will generate
|
||||
* this GSS-API token
|
||||
* @param maxTotalSize the pre-determined value that serves as a
|
||||
* maximum size for the complete GSS-API token (including a
|
||||
* GSSHeader)
|
||||
* @return the maximum size of mechanism token that can be used
|
||||
* so as to not exceed maxTotalSize with the GSS-API token
|
||||
*/
|
||||
public static int getMaxMechTokenSize(ObjectIdentifier mechOid,
|
||||
int maxTotalSize) {
|
||||
|
||||
int mechOidBytesSize = 0;
|
||||
try {
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
temp.putOID(mechOid);
|
||||
mechOidBytesSize = temp.toByteArray().length;
|
||||
} catch (IOException e) {
|
||||
}
|
||||
|
||||
// Subtract bytes needed for 0x60 tag and mechOidBytes
|
||||
maxTotalSize -= (1 + mechOidBytesSize);
|
||||
|
||||
// Subtract maximum len bytes
|
||||
maxTotalSize -= 5;
|
||||
|
||||
return maxTotalSize;
|
||||
|
||||
/*
|
||||
* Len field and mechanism token must fit in remaining
|
||||
* space. The range of the len field that we allow is
|
||||
* 1 through 5.
|
||||
*
|
||||
|
||||
int mechTokenSize = 0;
|
||||
for (int lenFieldSize = 1; lenFieldSize <= 5;
|
||||
lenFieldSize++) {
|
||||
mechTokenSize = maxTotalSize - lenFieldSize;
|
||||
if (getLenFieldSize(mechTokenSize + mechOidBytesSize +
|
||||
lenFieldSize) <= lenFieldSize)
|
||||
break;
|
||||
}
|
||||
|
||||
return mechTokenSize;
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to determine the number of bytes that will be need to encode
|
||||
* the length field of the GSSHeader.
|
||||
*/
|
||||
private int getLenFieldSize(int len) {
|
||||
int retVal = 1;
|
||||
if (len < 128) {
|
||||
retVal=1;
|
||||
} else if (len < (1 << 8)) {
|
||||
retVal=2;
|
||||
} else if (len < (1 << 16)) {
|
||||
retVal=3;
|
||||
} else if (len < (1 << 24)) {
|
||||
retVal=4;
|
||||
} else {
|
||||
retVal=5; // See getMaxMechTokenSize
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes this GSSHeader instance onto the provided OutputStream.
|
||||
* @param os the OutputStream to which the token should be written.
|
||||
* @return the number of bytes that are output as a result of this
|
||||
* encoding
|
||||
*/
|
||||
public int encode(OutputStream os) throws IOException {
|
||||
int retVal = 1 + mechOidBytes.length;
|
||||
os.write(TOKEN_ID);
|
||||
int length = mechOidBytes.length + mechTokenLength;
|
||||
retVal += putLength(length, os);
|
||||
os.write(mechOidBytes);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a length from the input stream, allowing for at most 32 bits of
|
||||
* encoding to be used. (Not the same as getting a tagged integer!)
|
||||
*
|
||||
* @return the length or -1 if indefinite length found.
|
||||
* @exception IOException on parsing error or unsupported lengths.
|
||||
*/
|
||||
// shameless lifted from sun.security.util.DerInputStream.
|
||||
private int getLength(InputStream in) throws IOException {
|
||||
return getLength(in.read(), in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a length from the input stream, allowing for at most 32 bits of
|
||||
* encoding to be used. (Not the same as getting a tagged integer!)
|
||||
*
|
||||
* @return the length or -1 if indefinite length found.
|
||||
* @exception IOException on parsing error or unsupported lengths.
|
||||
*/
|
||||
// shameless lifted from sun.security.util.DerInputStream.
|
||||
private int getLength(int lenByte, InputStream in) throws IOException {
|
||||
int value, tmp;
|
||||
|
||||
tmp = lenByte;
|
||||
if ((tmp & 0x080) == 0x00) { // short form, 1 byte datum
|
||||
value = tmp;
|
||||
} else { // long form or indefinite
|
||||
tmp &= 0x07f;
|
||||
|
||||
/*
|
||||
* NOTE: tmp == 0 indicates indefinite length encoded data.
|
||||
* tmp > 4 indicates more than 4Gb of data.
|
||||
*/
|
||||
if (tmp == 0)
|
||||
return -1;
|
||||
if (tmp < 0 || tmp > 4)
|
||||
throw new IOException("DerInputStream.getLength(): lengthTag="
|
||||
+ tmp + ", "
|
||||
+ ((tmp < 0) ? "incorrect DER encoding." : "too big."));
|
||||
|
||||
for (value = 0; tmp > 0; tmp --) {
|
||||
value <<= 8;
|
||||
value += 0x0ff & in.read();
|
||||
}
|
||||
if (value < 0) {
|
||||
throw new IOException("Invalid length bytes");
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Put the encoding of the length in the specified stream.
|
||||
*
|
||||
* @params len the length of the attribute.
|
||||
* @param out the outputstream to write the length to
|
||||
* @return the number of bytes written
|
||||
* @exception IOException on writing errors.
|
||||
*/
|
||||
// Shameless lifted from sun.security.util.DerOutputStream.
|
||||
private int putLength(int len, OutputStream out) throws IOException {
|
||||
int retVal = 0;
|
||||
if (len < 128) {
|
||||
out.write((byte)len);
|
||||
retVal=1;
|
||||
|
||||
} else if (len < (1 << 8)) {
|
||||
out.write((byte)0x081);
|
||||
out.write((byte)len);
|
||||
retVal=2;
|
||||
|
||||
} else if (len < (1 << 16)) {
|
||||
out.write((byte)0x082);
|
||||
out.write((byte)(len >> 8));
|
||||
out.write((byte)len);
|
||||
retVal=3;
|
||||
|
||||
} else if (len < (1 << 24)) {
|
||||
out.write((byte)0x083);
|
||||
out.write((byte)(len >> 16));
|
||||
out.write((byte)(len >> 8));
|
||||
out.write((byte)len);
|
||||
retVal=4;
|
||||
|
||||
} else {
|
||||
out.write((byte)0x084);
|
||||
out.write((byte)(len >> 24));
|
||||
out.write((byte)(len >> 16));
|
||||
out.write((byte)(len >> 8));
|
||||
out.write((byte)len);
|
||||
retVal=5;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
// XXX Call these two in some central class
|
||||
private void debug(String str) {
|
||||
System.err.print(str);
|
||||
}
|
||||
|
||||
private String getHexBytes(byte[] bytes, int len)
|
||||
throws IOException {
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0; i < len; i++) {
|
||||
|
||||
int b1 = (bytes[i]>>4) & 0x0f;
|
||||
int b2 = bytes[i] & 0x0f;
|
||||
|
||||
sb.append(Integer.toHexString(b1));
|
||||
sb.append(Integer.toHexString(b2));
|
||||
sb.append(' ');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user