/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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.
*/
/**
* This class is a base class for other token definitions that pertain to
* per-message GSS-API calls. Conceptually GSS-API has two types of
* per-message tokens: WrapToken and MicToken. They differ in the respect
* that a WrapToken carries additional plaintext or ciphertext application
* data besides just the sequence number and checksum. This class
* encapsulates the commonality in the structure of the WrapToken and the
* MicToken. This structure can be represented as:
* <p>
* <pre>
* 0..1 TOK_ID Identification field.
* 01 01 - Mic token
* 02 01 - Wrap token
* 2..3 SGN_ALG Checksum algorithm indicator.
* 00 00 - DES MAC MD5
* 01 00 - MD2.5
* 02 00 - DES MAC
* 04 00 - HMAC SHA1 DES3-KD
* 11 00 - RC4-HMAC
* 4..5 SEAL_ALG ff ff - none
* 00 00 - DES
* 02 00 - DES3-KD
* 10 00 - RC4-HMAC
* 6..7 Filler Contains ff ff
* 8..15 SND_SEQ Encrypted sequence number field.
* 16..s+15 SGN_CKSUM Checksum of plaintext padded data,
* calculated according to algorithm
* specified in SGN_ALG field.
* s+16..last Data encrypted or plaintext padded data
* </pre>
* Where "s" indicates the size of the checksum.
* <p>
* As always, this is preceeded by a GSSHeader.
*
* @author Mayank Upadhyay
* @author Ram Marti
* @see sun.security.jgss.GSSHeader
*/
/* Fields in header minus checksum size */
/**
* Filler data as defined in the specification of the Kerberos v5 GSS-API
* Mechanism.
*/
// Signing algorithm values (for the SNG_ALG field)
// From RFC 1964
/* Use a DES MAC MD5 checksum */
/* Use DES MAC checksum. */
// From draft-raeburn-cat-gssapi-krb5-3des-00
/* Use a HMAC SHA1 DES3 -KD checksum */
// Sealing algorithm values (for the SEAL_ALG field)
// RFC 1964
/**
* A value for the SEAL_ALG field that indicates that no encryption was
* used.
*/
/* Use DES CBC encryption algorithm. */
// From draft-raeburn-cat-gssapi-krb5-3des-00
/**
* Use DES3-KD sealing algorithm. (draft-raeburn-cat-gssapi-krb5-3des-00)
* This algorithm uses triple-DES with key derivation, with a usage
* value KG_USAGE_SEAL. Padding is still to 8-byte multiples, and the
* IV for encrypting application data is zero.
*/
private int seqNumber;
private boolean confState = true;
private boolean initiator = true;
/* cipher instance used by the corresponding GSSContext */
/**
* Constructs a MessageToken from a byte array. If there are more bytes
* in the array than needed, the extra bytes are simply ignroed.
*
* @param tokenId the token id that should be contained in this token as
* it is read.
* @param context the Kerberos context associated with this token
* @param tokenBytes the byte array containing the token
* @param tokenOffset the offset where the token begins
* @param tokenLen the length of the token
* @param prop the MessageProp structure in which the properties of the
* token should be stored.
* @throws GSSException if there is a problem parsing the token
*/
prop);
}
/**
* Constructs a MessageToken from an InputStream. Bytes will be read on
* demand and the thread might block if there are not enough bytes to
* complete the token.
*
* @param tokenId the token id that should be contained in this token as
* it is read.
* @param context the Kerberos context associated with this token
* @param is the InputStream from which to read
* @param prop the MessageProp structure in which the properties of the
* token should be stored.
* @throws GSSException if there is a problem reading from the
* InputStream or parsing the token
*/
try {
}
if (!confState) {
prop.setPrivacy(false);
}
encSeqNumber = new byte[8];
// debug("\n\tRead EncSeq#=" +
// getHexBytes(encSeqNumber, encSeqNumber.length));
// debug("\n\tRead checksum=" +
// getHexBytes(checksum, checksum.length));
// debug("\nLeaving MessageToken.Cons\n");
} catch (IOException e) {
}
}
/**
* Used to obtain the GSSHeader that was at the start of this
* token.
*/
return gssHeader;
}
/**
* Used to obtain the token id that was contained in this token.
* @return the token id in the token
*/
public final int getTokenId() {
return tokenId;
}
/**
* Used to obtain the encrypted sequence number in this token.
* @return the encrypted sequence number in the token
*/
public final byte[] getEncSeqNumber() {
return encSeqNumber;
}
/**
* Used to obtain the checksum that was contained in this token.
* @return the checksum in the token
*/
public final byte[] getChecksum() {
return checksum;
}
/**
* Used to determine if this token contains any encrypted data.
* @return true if it contains any encrypted data, false if there is only
* plaintext data or if there is no data.
*/
public final boolean getConfState() {
return confState;
}
/**
* Generates the checksum field and the encrypted sequence number
* field. The encrypted sequence number uses the 8 bytes of the checksum
* as an initial vector in a fixed DesCbc algorithm.
*
* @param prop the MessageProp structure that determines what sort of
* checksum and sealing algorithm should be used. The lower byte
* of qop determines the checksum algorithm while the upper byte
* determines the signing algorithm.
* Checksum values are:
* 0 - default (DES_MAC)
* 1 - MD5
* 2 - DES_MD5
* 3 - DES_MAC
* 4 - HMAC_SHA1
* Sealing values are:
* 0 - default (DES)
* 1 - DES
* 2 - DES3-KD
*
* @param optionalHeader an optional header that will be processed first
* during checksum calculation
*
* @param data the application data to checksum
* @param offset the offset where the data starts
* @param len the length of the data
*
* @param optionalTrailer an optional trailer that will be processed
* last during checksum calculation. e.g., padding that should be
* appended to the application data
*
* @throws GSSException if an error occurs in the checksum calculation or
* encryption sequence number calculation.
*/
byte[] optionalHeader,
byte[] optionalTrailer)
throws GSSException {
// debug("Inside MessageToken.genSignAndSeqNumber:\n");
if (qop != 0) {
qop = 0;
}
if (!confState) {
prop.setPrivacy(false);
}
// Create a token header with the correct sign and seal algorithm
// values.
// Calculate SGN_CKSUM
checksum =
// debug("\n\tCalc checksum=" +
// getHexBytes(checksum, checksum.length));
// Calculate SND_SEQ
seqNumberData = new byte[8];
// When using this RC4 based encryption type, the sequence number is
// always sent in big-endian rather than little-endian order.
if (cipherHelper.isArcFour()) {
} else {
// for all other etypes
}
if (!initiator) {
}
// debug("\n\tCalc seqNum=" +
// getHexBytes(seqNumberData, seqNumberData.length));
// debug("\n\tCalc encSeqNum=" +
// getHexBytes(encSeqNumber, encSeqNumber.length));
}
/**
* Verifies that the checksum field and sequence number direction bytes
* are valid and consistent with the application data.
*
* @param optionalHeader an optional header that will be processed first
* during checksum calculation.
*
* @param data the application data
* @param offset the offset where the data begins
* @param len the length of the application data
*
* @param optionalTrailer an optional trailer that will be processed last
* during checksum calculation. e.g., padding that should be appended to
* the application data
*
* @throws GSSException if an error occurs in the checksum calculation or
* encryption sequence number calculation.
*/
byte[] optionalTrailer)
throws GSSException {
// debug("\tIn verifySign:\n");
// debug("\t\tchecksum: [" + getHexBytes(checksum) + "]\n");
byte[] myChecksum =
// debug("\t\tmychecksum: [" + getHexBytes(myChecksum) +"]\n");
// debug("\t\tchecksum: [" + getHexBytes(checksum) + "]\n");
// debug("\t\tencSeqNumber: [" + getHexBytes(encSeqNumber)
// + "]\n");
// debug("\t\tseqNumberData: [" + getHexBytes(seqNumberData)
// + "]\n");
/*
* The token from the initiator has direction bytes 0x00 and
* the token from the acceptor has direction bytes 0xff.
*/
byte directionByte = 0;
if (initiator)
return true;
}
return false;
}
public final int getSequenceNumber() {
int sequenceNum = 0;
if (cipherHelper.isArcFour()) {
} else {
}
return sequenceNum;
}
/**
* Computes the checksum based on the algorithm stored in the
* tokenHeader.
*
* @param optionalHeader an optional header that will be processed first
* during checksum calculation.
*
* @param data the application data
* @param offset the offset where the data begins
* @param len the length of the application data
*
* @param optionalTrailer an optional trailer that will be processed last
* during checksum calculation. e.g., padding that should be appended to
* the application data
*
* @throws GSSException if an error occurs in the checksum calculation.
*/
byte[] optionalTrailer)
throws GSSException {
// debug("Will do getChecksum:\n");
/*
* For checksum calculation the token header bytes i.e., the first 8
* bytes following the GSSHeader, are logically prepended to the
* application data to bind the data to this particular token.
*
* Note: There is no such requirement wrt adding padding to the
* application data for checksumming, although the cryptographic
* algorithm used might itself apply some padding.
*/
byte[] existingHeader = optionalHeader;
byte[] checksumDataHeader = tokenHeaderBytes;
if (existingHeader != null) {
}
}
/**
* Constructs an empty MessageToken for the local context to send to
* the peer. It also increments the local sequence number in the
* Krb5Context instance it uses after obtaining the object lock for
* it.
*
* @param tokenId the token id that should be contained in this token
* @param context the Kerberos context associated with this token
*/
/*
debug("\n============================");
debug("\nMySessionKey=" +
getHexBytes(context.getMySessionKey().getBytes()));
debug("\nPeerSessionKey=" +
getHexBytes(context.getPeerSessionKey().getBytes()));
debug("\n============================\n");
*/
}
// Just for consistency check in Wrap
// debug("In MessageToken.Cons");
}
/**
* Encodes a GSSHeader and this token onto an OutputStream.
*
* @param os the OutputStream to which this should be written
* @throws GSSException if an error occurs while writing to the OutputStream
*/
// debug("Writing seqNumber: " + getHexBytes(encSeqNumber));
// debug("Writing checksum: " + getHexBytes(checksum));
}
/**
* Obtains the size of this token. Note that this excludes the size of
* the GSSHeader.
* @return token size
*/
return getTokenSize();
}
}
throws GSSException {
}
/**
* Obtains the conext key that is associated with this token.
* @return the context key
*/
/*
public final byte[] getContextKey() {
return contextKey;
}
*/
/**
* Obtains the encryption algorithm that should be used in this token
* given the state of confidentiality the application requested.
* Requested qop must be consistent with negotiated session key.
* @param confRequested true if the application desired confidentiality
* on this token, false otherwise
* @param qop the qop requested by the application
* @throws GSSException if qop is incompatible with the negotiated
* session key
*/
throws GSSException;
// ******************************************* //
// I N N E R C L A S S E S F O L L O W
// ******************************************* //
/**
* This inner class represents the initial portion of the message token
* and contains information about the checksum and encryption algorithms
* that are in use. It constitutes the first 8 bytes of the
* message token:
* <pre>
* 0..1 TOK_ID Identification field.
* 01 01 - Mic token
* 02 01 - Wrap token
* 2..3 SGN_ALG Checksum algorithm indicator.
* 00 00 - DES MAC MD5
* 01 00 - MD2.5
* 02 00 - DES MAC
* 04 00 - HMAC SHA1 DES3-KD
* 11 00 - RC4-HMAC
* 4..5 SEAL_ALG ff ff - none
* 00 00 - DES
* 02 00 - DES3-KD
* 10 00 - RC4-HMAC
* 6..7 Filler Contains ff ff
* </pre>
*/
class MessageTokenHeader {
private int tokenId;
private int signAlg;
private int sealAlg;
/**
* Constructs a MessageTokenHeader for the specified token type with
* appropriate checksum and encryption algorithms fields.
*
* @param tokenId the token id for this mesage token
* @param conf true if confidentiality will be resuested with this
* message token, false otherwise.
* @param qop the value of the quality of protection that will be
* desired.
*/
throws GSSException {
}
/**
* Constructs a MessageTokenHeader by reading it from an InputStream
* and sets the appropriate confidentiality and quality of protection
* values in a MessageProp structure.
*
* @param is the InputStream to read from
* @param prop the MessageProp to populate
* @throws IOException is an error occurs while reading from the
* InputStream
*/
throws IOException {
// debug("\nMessageTokenHeader read tokenId=" +
// getHexBytes(bytes) + "\n");
// XXX compare to FILLER
// debug("SIGN_ALG=" + signAlg);
switch (sealAlg) {
case SEAL_ALG_DES:
case SEAL_ALG_DES3_KD:
case SEAL_ALG_ARCFOUR_HMAC:
prop.setPrivacy(true);
break;
default:
prop.setPrivacy(false);
}
}
/**
* Encodes this MessageTokenHeader onto an OutputStream
* @param os the OutputStream to write to
* @throws IOException is an error occurs while writing
*/
}
/**
* Returns the token id for the message token.
* @return the token id
* @see sun.security.jgss.krb5.Krb5Token#MIC_ID
* @see sun.security.jgss.krb5.Krb5Token#WRAP_ID
*/
public final int getTokenId() {
return tokenId;
}
/**
* Returns the sign algorithm for the message token.
* @return the sign algorithm
* @see sun.security.jgss.krb5.MessageToken#SIGN_DES_MAC
* @see sun.security.jgss.krb5.MessageToken#SIGN_DES_MAC_MD5
*/
public final int getSignAlg() {
return signAlg;
}
/**
* Returns the seal algorithm for the message token.
* @return the seal algorithm
* @see sun.security.jgss.krb5.MessageToken#SEAL_ALG_DES
* @see sun.security.jgss.krb5.MessageToken#SEAL_ALG_NONE
*/
public final int getSealAlg() {
return sealAlg;
}
/**
* Returns the bytes of this header.
* @return 8 bytes that form this header
*/
public final byte[] getBytes() {
return bytes;
}
} // end of class MessageTokenHeader
/**
* Determine signing algorithm based on QOP.
*/
// QOP ignored
return cipherHelper.getSgnAlg();
}
}