Merge "Add lint-baseline.txt files for ike"
diff --git a/src/java/android/net/ipsec/ike/TunnelModeChildSessionParams.java b/src/java/android/net/ipsec/ike/TunnelModeChildSessionParams.java
index 10a23db..c8d31f6 100644
--- a/src/java/android/net/ipsec/ike/TunnelModeChildSessionParams.java
+++ b/src/java/android/net/ipsec/ike/TunnelModeChildSessionParams.java
@@ -95,29 +95,10 @@
     }
 
     /** Represents an IPv4 DHCP server request */
-    public interface ConfigRequestIpv4DhcpServer extends TunnelModeChildConfigRequest {
-        /**
-         * Retrieves the requested IPv4 DHCP server address
-         *
-         * @return The requested DHCP server address, or null if no specific DHCP server was
-         *     requested
-         * @hide
-         */
-        @Nullable
-        Inet4Address getAddress();
-    }
+    public interface ConfigRequestIpv4DhcpServer extends TunnelModeChildConfigRequest {}
 
     /** Represents an IPv4 DNS Server request */
-    public interface ConfigRequestIpv4DnsServer extends TunnelModeChildConfigRequest {
-        /**
-         * Retrieves the requested IPv4 DNS server address
-         *
-         * @return The requested DNS server address, or null if no specific DNS server was requested
-         * @hide
-         */
-        @Nullable
-        Inet4Address getAddress();
-    }
+    public interface ConfigRequestIpv4DnsServer extends TunnelModeChildConfigRequest {}
 
     /** Represents an IPv4 Netmask request */
     public interface ConfigRequestIpv4Netmask extends TunnelModeChildConfigRequest {}
@@ -141,16 +122,7 @@
     }
 
     /** Represents an IPv6 DNS Server request */
-    public interface ConfigRequestIpv6DnsServer extends TunnelModeChildConfigRequest {
-        /**
-         * Retrieves the requested IPv6 DNS server address
-         *
-         * @return The requested DNS server address, or null if no specific DNS server was requested
-         * @hide
-         */
-        @Nullable
-        Inet6Address getAddress();
-    }
+    public interface ConfigRequestIpv6DnsServer extends TunnelModeChildConfigRequest {}
 
     /** This class can be used to incrementally construct a {@link TunnelModeChildSessionParams}. */
     public static final class Builder extends ChildSessionParams.Builder {
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeCertReqPayload.java b/src/java/com/android/internal/net/ipsec/ike/message/IkeCertReqPayload.java
new file mode 100644
index 0000000..92f3207
--- /dev/null
+++ b/src/java/com/android/internal/net/ipsec/ike/message/IkeCertReqPayload.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2020 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.internal.net.ipsec.ike.message;
+
+import static com.android.internal.net.ipsec.ike.message.IkeCertPayload.CERT_ENCODING_LEN;
+import static com.android.internal.net.ipsec.ike.message.IkeCertPayload.CertificateEncoding;
+
+import android.net.ipsec.ike.exceptions.IkeProtocolException;
+
+import java.nio.ByteBuffer;
+
+/**
+ * This class represents a Certificate Request Payload
+ *
+ * <p>A Certificate Request Payload provides suggestion for an end certificate to select. Receiver
+ * of this payload is allowed to send an alternate. It is possible that there is a preferred CA sent
+ * in the IkeCertReqPayload, but an alternate is still acceptable.
+ *
+ * <p>IKE library will always ignore this payload since only one end certificate can be configured
+ * by users.
+ *
+ * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.8">RFC 7296, Internet Key Exchange
+ *     Protocol Version 2 (IKEv2)</a>
+ */
+public class IkeCertReqPayload extends IkePayload {
+    /** Certificate encoding type */
+    @CertificateEncoding public final int certEncodingType;
+    /** Concatenated list of SHA-1 hashes of CAs' Subject Public Key Info */
+    public final byte[] caSubjectPublicKeyInforHashes;
+
+    /**
+     * Construct an instance of IkeCertReqPayload from decoding an inbound IKE packet.
+     *
+     * <p>NegativeArraySizeException and BufferUnderflowException will be caught in {@link
+     * IkeMessage}
+     *
+     * @param critical indicates if this payload is critical. Ignored in supported payload as
+     *     instructed by the RFC 7296.
+     * @param payloadBody payload body in byte array
+     * @throws IkeProtocolException if there is any error
+     */
+    public IkeCertReqPayload(boolean critical, byte[] payloadBody) throws IkeProtocolException {
+        super(PAYLOAD_TYPE_CERT_REQUEST, critical);
+
+        ByteBuffer inputBuffer = ByteBuffer.wrap(payloadBody);
+        certEncodingType = Byte.toUnsignedInt(inputBuffer.get());
+        caSubjectPublicKeyInforHashes = new byte[inputBuffer.remaining()];
+        inputBuffer.get(caSubjectPublicKeyInforHashes);
+    }
+
+    /**
+     * Encode Certificate Request Payload to ByteBuffer.
+     *
+     * @param nextPayload type of payload that follows this payload.
+     * @param byteBuffer destination ByteBuffer that stores encoded payload.
+     */
+    @Override
+    protected void encodeToByteBuffer(@PayloadType int nextPayload, ByteBuffer byteBuffer) {
+        encodePayloadHeaderToByteBuffer(nextPayload, getPayloadLength(), byteBuffer);
+
+        byteBuffer.put((byte) certEncodingType).put(caSubjectPublicKeyInforHashes);
+    }
+
+    /**
+     * Get entire payload length.
+     *
+     * @return entire payload length.
+     */
+    @Override
+    protected int getPayloadLength() {
+        return GENERIC_HEADER_LENGTH + CERT_ENCODING_LEN + caSubjectPublicKeyInforHashes.length;
+    }
+
+    /**
+     * Return the payload type as a String.
+     *
+     * @return the payload type as a String.
+     */
+    @Override
+    public String getTypeString() {
+        return "CertReq";
+    }
+}
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeConfigPayload.java b/src/java/com/android/internal/net/ipsec/ike/message/IkeConfigPayload.java
index bb5f9a3..778faa4 100644
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeConfigPayload.java
+++ b/src/java/com/android/internal/net/ipsec/ike/message/IkeConfigPayload.java
@@ -538,7 +538,6 @@
             super(CONFIG_ATTR_INTERNAL_IP4_DHCP, value);
         }
 
-        @Override
         public Inet4Address getAddress() {
             return address;
         }
@@ -572,7 +571,6 @@
             super(CONFIG_ATTR_INTERNAL_IP4_DNS, value);
         }
 
-        @Override
         public Inet4Address getAddress() {
             return address;
         }
@@ -979,7 +977,6 @@
             super(CONFIG_ATTR_INTERNAL_IP6_DNS, value);
         }
 
-        @Override
         public Inet6Address getAddress() {
             return address;
         }
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkePayloadFactory.java b/src/java/com/android/internal/net/ipsec/ike/message/IkePayloadFactory.java
index 2f191d4..b50f093 100644
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkePayloadFactory.java
+++ b/src/java/com/android/internal/net/ipsec/ike/message/IkePayloadFactory.java
@@ -60,7 +60,6 @@
                 int payloadType, boolean isCritical, boolean isResp, byte[] payloadBody)
                 throws IkeProtocolException {
             switch (payloadType) {
-                    // TODO: Add cases for creating supported payloads.
                 case IkePayload.PAYLOAD_TYPE_SA:
                     return new IkeSaPayload(isCritical, isResp, payloadBody);
                 case IkePayload.PAYLOAD_TYPE_KE:
@@ -71,6 +70,8 @@
                     return new IkeIdPayload(isCritical, payloadBody, false);
                 case IkePayload.PAYLOAD_TYPE_CERT:
                     return IkeCertPayload.getIkeCertPayload(isCritical, payloadBody);
+                case IkeCertReqPayload.PAYLOAD_TYPE_CERT_REQUEST:
+                    return new IkeCertReqPayload(isCritical, payloadBody);
                 case IkePayload.PAYLOAD_TYPE_AUTH:
                     return IkeAuthPayload.getIkeAuthPayload(isCritical, payloadBody);
                 case IkePayload.PAYLOAD_TYPE_NONCE:
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeCertReqPayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeCertReqPayloadTest.java
new file mode 100644
index 0000000..f859a82
--- /dev/null
+++ b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeCertReqPayloadTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2020 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.internal.net.ipsec.ike.message;
+
+import static com.android.internal.net.ipsec.ike.message.IkeCertPayload.CERTIFICATE_ENCODING_X509_CERT_SIGNATURE;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import android.util.Pair;
+
+import com.android.internal.net.TestUtils;
+
+import org.junit.Test;
+
+import java.nio.ByteBuffer;
+
+public class IkeCertReqPayloadTest {
+    private static final int CERT_ENCODING_TYPE = CERTIFICATE_ENCODING_X509_CERT_SIGNATURE;
+    private static final int NEXT_PAYLOAD_TYPE = IkePayload.PAYLOAD_TYPE_AUTH;
+    private static final byte[] CERT_REQ_PAYLOAD =
+            TestUtils.hexStringToByteArray("27000019040d0a12bb1f98996563f15b10db95c67eea7990fa");
+    private static final byte[] CA_SUBJECT_PUBLIC_KEY_INFO_HASH =
+            TestUtils.hexStringToByteArray("0d0a12bb1f98996563f15b10db95c67eea7990fa");
+
+    @Test
+    public void testDecode() throws Exception {
+        Pair<IkePayload, Integer> pair =
+                IkePayloadFactory.getIkePayload(
+                        IkePayload.PAYLOAD_TYPE_CERT_REQUEST,
+                        false /*isResp*/,
+                        ByteBuffer.wrap(CERT_REQ_PAYLOAD));
+
+        IkeCertReqPayload certPayload = (IkeCertReqPayload) pair.first;
+        assertEquals(CERT_ENCODING_TYPE, certPayload.certEncodingType);
+        assertArrayEquals(
+                CA_SUBJECT_PUBLIC_KEY_INFO_HASH, certPayload.caSubjectPublicKeyInforHashes);
+
+        assertEquals(NEXT_PAYLOAD_TYPE, (int) pair.second);
+    }
+
+    @Test
+    public void testEncode() throws Exception {
+        Pair<IkePayload, Integer> pair =
+                IkePayloadFactory.getIkePayload(
+                        IkePayload.PAYLOAD_TYPE_CERT_REQUEST,
+                        false /*isResp*/,
+                        ByteBuffer.wrap(CERT_REQ_PAYLOAD));
+        IkeCertReqPayload certPayload = (IkeCertReqPayload) pair.first;
+
+        ByteBuffer byteBuffer = ByteBuffer.allocate(CERT_REQ_PAYLOAD.length);
+        certPayload.encodeToByteBuffer(NEXT_PAYLOAD_TYPE, byteBuffer);
+        assertArrayEquals(CERT_REQ_PAYLOAD, byteBuffer.array());
+
+        assertEquals(CERT_REQ_PAYLOAD.length, certPayload.getPayloadLength());
+    }
+}