/* * ProtocolEncoder.java * Created on 2011-07-21 * * Copyright (c) Verax Systems 2011. * All rights reserved. * * This software is furnished under a license. Use, duplication, * disclosure and all other uses are restricted to the rights * specified in the written license agreement. */ package com.veraxsystems.vxipmi.coding.protocol.encoder; import java.security.InvalidKeyException; import com.veraxsystems.vxipmi.coding.protocol.AuthenticationType; import com.veraxsystems.vxipmi.coding.protocol.IpmiMessage; import com.veraxsystems.vxipmi.common.TypeConverter; /** * Adds IPMI session header to encrypted payload. Should be used to encode * regular RMCP+ messages (excluding Open Session and RAKP Messages) */ public abstract class ProtocolEncoder implements IpmiEncoder { /** * Encodes IPMI message. * * @param ipmiMessage * - IPMI message to encode. * @return IPMI message encoded into byte array. * @throws InvalidKeyException * - when initiation of the confidentiality algorithm fails * @see IpmiMessage */ @Override public abstract byte[] encode(IpmiMessage ipmiMessage) throws InvalidKeyException; protected byte encodeAuthenticationType( AuthenticationType authenticationType) { return TypeConverter.intToByte(authenticationType.getCode()); } /** * Converts integer value into byte array using little endian convention and * inserts it into message at given offset. * * @param value * @param message * - IPMI message being created * @param offset * @throws IndexOutOfBoundsException * when message is too short to hold value at given offset */ protected void encodeInt(int value, byte[] message, int offset) throws IndexOutOfBoundsException { byte[] array = TypeConverter.intToLittleEndianByteArray(value); if (array.length + offset > message.length) { throw new IndexOutOfBoundsException("Message is too short"); } System.arraycopy(array, 0, message, offset, array.length); } /** * Encodes session sequence number and inserts it into message at given * offset. * * @param value * @param message * - IPMI message being created * @param offset * @throws IndexOutOfBoundsException * when message is too short to hold value at given offset */ protected void encodeSessionSequenceNumber(int value, byte[] message, int offset) throws IndexOutOfBoundsException { encodeInt(value, message, offset); } /** * Encodes session id and inserts it into message at given offset. * * @param value * @param message * - IPMI message being created * @param offset * @throws IndexOutOfBoundsException * when message is too short to hold value at given offset */ protected void encodeSessionId(int value, byte[] message, int offset) throws IndexOutOfBoundsException { encodeInt(value, message, offset); } /** * Encodes payload length and inserts it into message at given offset. * * @param value * @param message * - IPMI message being created * @param offset * @throws IndexOutOfBoundsException * when message is too short to hold value at given offset */ protected abstract void encodePayloadLength(int value, byte[] message, int offset) throws IndexOutOfBoundsException; /** * Encodes payload and inserts it into message at given offset. <br> * When payload == null it will not be inserted. * * @param payload * - IPMI payload to encode. * @param message * - IPMI message being created. * @param offset * @throws IndexOutOfBoundsException * when message is too short to hold value at given offset * @return offset + encoded message length */ protected int encodePayload(byte[] payload, byte[] message, int offset) throws IndexOutOfBoundsException { if (payload == null) { return offset; } if (payload.length + offset > message.length) { throw new IndexOutOfBoundsException("Message is too short"); } System.arraycopy(payload, 0, message, offset, payload.length); return offset + payload.length; } }