/** * Computes the checksum based on the algorithm stored in the tokenHeader. * * @param data the application data * @param offset the offset where the data begins * @param len the length of the application data * @throws GSSException if an error occurs in the checksum calculation. */ byte[] getChecksum(byte[] data, int offset, int len) throws GSSException { // debug("Will do getChecksum:\n"); /* * For checksum calculation the token header bytes i.e., the first 16 * 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[] tokenHeaderBytes = tokenHeader.getBytes(); // check confidentiality int conf_flag = tokenHeaderBytes[TOKEN_FLAG_POS] & FLAG_WRAP_CONFIDENTIAL; // clear EC and RRC in token header for checksum calculation if ((conf_flag == 0) && (tokenId == WRAP_ID_v2)) { tokenHeaderBytes[4] = 0; tokenHeaderBytes[5] = 0; tokenHeaderBytes[6] = 0; tokenHeaderBytes[7] = 0; } return cipherHelper.calculateChecksum(tokenHeaderBytes, data, offset, len, key_usage); }
/** * Generates the checksum field and the sequence number field. * * @param prop the MessageProp structure * @param data the application data to checksum * @param offset the offset where the data starts * @param len the length of the data * @throws GSSException if an error occurs in the checksum calculation or sequence number * calculation. */ public void genSignAndSeqNumber(MessageProp prop, byte[] data, int offset, int len) throws GSSException { // debug("Inside MessageToken.genSignAndSeqNumber:\n"); int qop = prop.getQOP(); if (qop != 0) { qop = 0; prop.setQOP(qop); } if (!confState) { prop.setPrivacy(false); } // Create a new gss token header as defined in RFC 4121 tokenHeader = new MessageTokenHeader(tokenId, prop.getPrivacy()); // debug("\n\t Message Header = " + // getHexBytes(tokenHeader.getBytes(), tokenHeader.getBytes().length)); // set key_usage if (tokenId == Krb5Token.WRAP_ID_v2) { key_usage = (initiator ? KG_USAGE_INITIATOR_SEAL : KG_USAGE_ACCEPTOR_SEAL); } else if (tokenId == Krb5Token.MIC_ID_v2) { key_usage = (initiator ? KG_USAGE_INITIATOR_SIGN : KG_USAGE_ACCEPTOR_SIGN); } // Calculate SGN_CKSUM if ((tokenId == MIC_ID_v2) || (!prop.getPrivacy() && (tokenId == WRAP_ID_v2))) { checksum = getChecksum(data, offset, len); // debug("\n\tCalc checksum=" + // getHexBytes(checksum, checksum.length)); } // In Wrap tokens without confidentiality, the EC field SHALL be used // to encode the number of octets in the trailing checksum if (!prop.getPrivacy() && (tokenId == WRAP_ID_v2)) { byte[] tok_header = tokenHeader.getBytes(); tok_header[4] = (byte) (checksum.length >>> 8); tok_header[5] = (byte) (checksum.length); } }
protected final byte[] getTokenHeader() { return (tokenHeader.getBytes()); }