blob: 2474bb64f11fe90029cf706905317195bafd280c [file] [log] [blame]
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.ike.ikev2.message;
import android.annotation.IntDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.ByteBuffer;
/**
* IkePayload is an abstract class that represents the common information for all IKE payload types.
*
* <p>Each types of IKE payload should implement its own subclass with its own decoding and encoding
* logic.
*
* @see <a href="https://tools.ietf.org/html/rfc7296#section-3.2">RFC 7296, Internet Key Exchange
* Protocol Version 2 (IKEv2)</a>
*/
public abstract class IkePayload {
// Critical bit and following reserved 7 bits in payload generic header must all be zero
private static final byte PAYLOAD_HEADER_CRITICAL_BIT_UNSET = 0;
/** Length of a generic IKE payload header */
public static final int GENERIC_HEADER_LENGTH = 4;
/**
* Payload types as defined by IANA:
*
* @see <a href="https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml">
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({
PAYLOAD_TYPE_NO_NEXT,
PAYLOAD_TYPE_SA,
PAYLOAD_TYPE_KE,
PAYLOAD_TYPE_CERT,
PAYLOAD_TYPE_AUTH,
PAYLOAD_TYPE_ID_INITIATOR,
PAYLOAD_TYPE_ID_RESPONDER,
PAYLOAD_TYPE_NONCE,
PAYLOAD_TYPE_NOTIFY,
PAYLOAD_TYPE_DELETE,
PAYLOAD_TYPE_VENDOR,
PAYLOAD_TYPE_TS_INITIATOR,
PAYLOAD_TYPE_TS_RESPONDER,
PAYLOAD_TYPE_SK
})
public @interface PayloadType {}
/** No Next Payload */
public static final int PAYLOAD_TYPE_NO_NEXT = 0;
/** Security Association Payload */
public static final int PAYLOAD_TYPE_SA = 33;
/** Key Exchange Payload */
public static final int PAYLOAD_TYPE_KE = 34;
/** Identification Payload for IKE SA Initiator */
public static final int PAYLOAD_TYPE_ID_INITIATOR = 35;
/** Identification Payload for IKE SA Responder */
public static final int PAYLOAD_TYPE_ID_RESPONDER = 36;
/** Certification Payload */
public static final int PAYLOAD_TYPE_CERT = 37;
/** Authentication Payload */
public static final int PAYLOAD_TYPE_AUTH = 39;
/** Nonce Payload */
public static final int PAYLOAD_TYPE_NONCE = 40;
/** Notify Payload */
public static final int PAYLOAD_TYPE_NOTIFY = 41;
/** Delete Payload */
public static final int PAYLOAD_TYPE_DELETE = 42;
/** Vendor Payload */
public static final int PAYLOAD_TYPE_VENDOR = 43;
/** Traffic Selector Payload of Child SA Initiator */
public static final int PAYLOAD_TYPE_TS_INITIATOR = 44;
/** Traffic Selector Payload of Child SA Responder */
public static final int PAYLOAD_TYPE_TS_RESPONDER = 45;
/** Encrypted and Authenticated Payload */
public static final int PAYLOAD_TYPE_SK = 46;
// TODO: List all payload types.
@Retention(RetentionPolicy.SOURCE)
@IntDef({
PROTOCOL_ID_UNSET,
PROTOCOL_ID_IKE,
PROTOCOL_ID_AH,
PROTOCOL_ID_ESP,
})
public @interface ProtocolId {}
public static final int PROTOCOL_ID_UNSET = 0;
public static final int PROTOCOL_ID_IKE = 1;
public static final int PROTOCOL_ID_AH = 2;
public static final int PROTOCOL_ID_ESP = 3;
public static final byte SPI_LEN_NOT_INCLUDED = 0;
public static final byte SPI_LEN_IPSEC = 4;
public static final byte SPI_LEN_IKE = 8;
public static final int SPI_NOT_INCLUDED = 0;
/** Length of port number in bytes */
public static final int IP_PORT_LEN = 2;
public final int payloadType;
public final boolean isCritical;
/**
* Construct a instance of IkePayload in the context of a IkePayloadFactory.
*
* <p>It should be overrided by subclass of IkePayload
*
* @param payload the payload type. All supported types will fall in {@link
* IkePayload.PayloadType}
* @param critical indicates if this payload is critical. Ignore it when payload type is
* supported.
*/
IkePayload(int payload, boolean critical) {
payloadType = payload;
isCritical = critical;
}
/**
* Encode generic payload header to ByteBuffer.
*
* @param nextPayload type of payload that follows this payload.
* @param payloadLength length of the entire payload
* @param byteBuffer destination ByteBuffer that stores encoded payload header
*/
protected static void encodePayloadHeaderToByteBuffer(
@PayloadType int nextPayload, int payloadLength, ByteBuffer byteBuffer) {
byteBuffer
.put((byte) nextPayload)
.put(PAYLOAD_HEADER_CRITICAL_BIT_UNSET)
.putShort((short) payloadLength);
}
/**
* Encode payload to ByteBuffer.
*
* @param nextPayload type of payload that follows this payload.
* @param byteBuffer destination ByteBuffer that stores encoded payload.
*/
protected abstract void encodeToByteBuffer(@PayloadType int nextPayload, ByteBuffer byteBuffer);
/**
* Get entire payload length.
*
* @return entire payload length.
*/
protected abstract int getPayloadLength();
/**
* Return the payload type as a String.
*
* @return the payload type as a String.
*/
public abstract String getTypeString();
}