Merge "Fix bug in outbound fragment integrity checksum"
diff --git a/Android.bp b/Android.bp
index 8e7717a..f954c1c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -98,6 +98,7 @@
"framework-module-api-defaults-module_libs_api",
"ike-stubs-defaults",
],
+ dist: { dest: "android.net.ipsec.ike.txt" },
}
droidstubs {
@@ -112,4 +113,5 @@
name: "android.net.ipsec.ike.stubs.module_libs_api",
srcs: [":android.net.ipsec.ike.stubs.sources.module_libs_api"],
defaults: ["framework-module-stubs-lib-defaults-module_libs_api"],
+ dist: { dest: "android.net.ipsec.ike.jar" },
}
diff --git a/api/system-lint-baseline.txt b/api/system-lint-baseline.txt
new file mode 100644
index 0000000..bec7683
--- /dev/null
+++ b/api/system-lint-baseline.txt
@@ -0,0 +1,75 @@
+// Baseline format: 1.0
+BuilderSetStyle: android.net.ipsec.ike.IkeSessionParams.Builder#removeIkeOption(int):
+ Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.net.ipsec.ike.IkeSessionParams.Builder.removeIkeOption(int)
+
+
+CallbackInterface: android.net.ipsec.ike.ChildSessionCallback:
+ Callbacks must be abstract class instead of interface to enable extension in future API levels: ChildSessionCallback
+CallbackInterface: android.net.ipsec.ike.IkeSessionCallback:
+ Callbacks must be abstract class instead of interface to enable extension in future API levels: IkeSessionCallback
+
+
+MethodNameUnits: android.net.ipsec.ike.IkeSessionParams#getDpdDelaySeconds():
+ Returned time values must be in milliseconds, was `getDpdDelaySeconds`
+
+
+MissingGetterMatchingBuilder: android.net.eap.EapSessionConfig.Builder#setEapMsChapV2Config(String, String):
+ android.net.eap.EapSessionConfig does not declare a `getEapMsChapV2Config()` method matching method android.net.eap.EapSessionConfig.Builder.setEapMsChapV2Config(String,String)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.ChildSaProposal.Builder#addDhGroup(int):
+ android.net.ipsec.ike.ChildSaProposal does not declare a `getDhGroups()` method matching method android.net.ipsec.ike.ChildSaProposal.Builder.addDhGroup(int)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.ChildSaProposal.Builder#addEncryptionAlgorithm(int, int):
+ android.net.ipsec.ike.ChildSaProposal does not declare a `getEncryptionAlgorithms()` method matching method android.net.ipsec.ike.ChildSaProposal.Builder.addEncryptionAlgorithm(int,int)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.ChildSaProposal.Builder#addIntegrityAlgorithm(int):
+ android.net.ipsec.ike.ChildSaProposal does not declare a `getIntegrityAlgorithms()` method matching method android.net.ipsec.ike.ChildSaProposal.Builder.addIntegrityAlgorithm(int)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.IkeSaProposal.Builder#addDhGroup(int):
+ android.net.ipsec.ike.IkeSaProposal does not declare a `getDhGroups()` method matching method android.net.ipsec.ike.IkeSaProposal.Builder.addDhGroup(int)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.IkeSaProposal.Builder#addEncryptionAlgorithm(int, int):
+ android.net.ipsec.ike.IkeSaProposal does not declare a `getEncryptionAlgorithms()` method matching method android.net.ipsec.ike.IkeSaProposal.Builder.addEncryptionAlgorithm(int,int)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.IkeSaProposal.Builder#addIntegrityAlgorithm(int):
+ android.net.ipsec.ike.IkeSaProposal does not declare a `getIntegrityAlgorithms()` method matching method android.net.ipsec.ike.IkeSaProposal.Builder.addIntegrityAlgorithm(int)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.IkeSessionParams.Builder#addIkeOption(int):
+ android.net.ipsec.ike.IkeSessionParams does not declare a `getIkeOptions()` method matching method android.net.ipsec.ike.IkeSessionParams.Builder.addIkeOption(int)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.IkeSessionParams.Builder#addPcscfServerRequest(int):
+ android.net.ipsec.ike.IkeSessionParams does not declare a `getPcscfServerRequests()` method matching method android.net.ipsec.ike.IkeSessionParams.Builder.addPcscfServerRequest(int)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.IkeSessionParams.Builder#addPcscfServerRequest(java.net.InetAddress):
+ android.net.ipsec.ike.IkeSessionParams does not declare a `getPcscfServerRequests()` method matching method android.net.ipsec.ike.IkeSessionParams.Builder.addPcscfServerRequest(java.net.InetAddress)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.IkeSessionParams.Builder#setAuthDigitalSignature(java.security.cert.X509Certificate, java.security.cert.X509Certificate, java.security.PrivateKey):
+ android.net.ipsec.ike.IkeSessionParams does not declare a `getAuthDigitalSignature()` method matching method android.net.ipsec.ike.IkeSessionParams.Builder.setAuthDigitalSignature(java.security.cert.X509Certificate,java.security.cert.X509Certificate,java.security.PrivateKey)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.IkeSessionParams.Builder#setAuthDigitalSignature(java.security.cert.X509Certificate, java.security.cert.X509Certificate, java.util.List<java.security.cert.X509Certificate>, java.security.PrivateKey):
+ android.net.ipsec.ike.IkeSessionParams does not declare a `getAuthDigitalSignature()` method matching method android.net.ipsec.ike.IkeSessionParams.Builder.setAuthDigitalSignature(java.security.cert.X509Certificate,java.security.cert.X509Certificate,java.util.List<java.security.cert.X509Certificate>,java.security.PrivateKey)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.IkeSessionParams.Builder#setAuthEap(java.security.cert.X509Certificate, android.net.eap.EapSessionConfig):
+ android.net.ipsec.ike.IkeSessionParams does not declare a `getAuthEap()` method matching method android.net.ipsec.ike.IkeSessionParams.Builder.setAuthEap(java.security.cert.X509Certificate,android.net.eap.EapSessionConfig)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.IkeSessionParams.Builder#setAuthPsk(byte[]):
+ android.net.ipsec.ike.IkeSessionParams does not declare a `getAuthPsk()` method matching method android.net.ipsec.ike.IkeSessionParams.Builder.setAuthPsk(byte[])
+MissingGetterMatchingBuilder: android.net.ipsec.ike.IkeSessionParams.Builder#setLifetimeSeconds(int, int):
+ android.net.ipsec.ike.IkeSessionParams does not declare a `getLifetimeSeconds()` method matching method android.net.ipsec.ike.IkeSessionParams.Builder.setLifetimeSeconds(int,int)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.TransportModeChildSessionParams.Builder#addInboundTrafficSelectors(android.net.ipsec.ike.IkeTrafficSelector):
+ android.net.ipsec.ike.TransportModeChildSessionParams does not declare a `getInboundTrafficSelectorss()` method matching method android.net.ipsec.ike.TransportModeChildSessionParams.Builder.addInboundTrafficSelectors(android.net.ipsec.ike.IkeTrafficSelector)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.TransportModeChildSessionParams.Builder#addOutboundTrafficSelectors(android.net.ipsec.ike.IkeTrafficSelector):
+ android.net.ipsec.ike.TransportModeChildSessionParams does not declare a `getOutboundTrafficSelectorss()` method matching method android.net.ipsec.ike.TransportModeChildSessionParams.Builder.addOutboundTrafficSelectors(android.net.ipsec.ike.IkeTrafficSelector)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.TransportModeChildSessionParams.Builder#addSaProposal(android.net.ipsec.ike.ChildSaProposal):
+ android.net.ipsec.ike.TransportModeChildSessionParams does not declare a `getSaProposals()` method matching method android.net.ipsec.ike.TransportModeChildSessionParams.Builder.addSaProposal(android.net.ipsec.ike.ChildSaProposal)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.TransportModeChildSessionParams.Builder#setLifetimeSeconds(int, int):
+ android.net.ipsec.ike.TransportModeChildSessionParams does not declare a `getLifetimeSeconds()` method matching method android.net.ipsec.ike.TransportModeChildSessionParams.Builder.setLifetimeSeconds(int,int)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.TunnelModeChildSessionParams.Builder#addInboundTrafficSelectors(android.net.ipsec.ike.IkeTrafficSelector):
+ android.net.ipsec.ike.TunnelModeChildSessionParams does not declare a `getInboundTrafficSelectorss()` method matching method android.net.ipsec.ike.TunnelModeChildSessionParams.Builder.addInboundTrafficSelectors(android.net.ipsec.ike.IkeTrafficSelector)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.TunnelModeChildSessionParams.Builder#addInternalAddressRequest(int):
+ android.net.ipsec.ike.TunnelModeChildSessionParams does not declare a `getInternalAddressRequests()` method matching method android.net.ipsec.ike.TunnelModeChildSessionParams.Builder.addInternalAddressRequest(int)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.TunnelModeChildSessionParams.Builder#addInternalAddressRequest(java.net.Inet4Address):
+ android.net.ipsec.ike.TunnelModeChildSessionParams does not declare a `getInternalAddressRequests()` method matching method android.net.ipsec.ike.TunnelModeChildSessionParams.Builder.addInternalAddressRequest(java.net.Inet4Address)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.TunnelModeChildSessionParams.Builder#addInternalAddressRequest(java.net.Inet6Address, int):
+ android.net.ipsec.ike.TunnelModeChildSessionParams does not declare a `getInternalAddressRequests()` method matching method android.net.ipsec.ike.TunnelModeChildSessionParams.Builder.addInternalAddressRequest(java.net.Inet6Address,int)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.TunnelModeChildSessionParams.Builder#addInternalDhcpServerRequest(int):
+ android.net.ipsec.ike.TunnelModeChildSessionParams does not declare a `getInternalDhcpServerRequests()` method matching method android.net.ipsec.ike.TunnelModeChildSessionParams.Builder.addInternalDhcpServerRequest(int)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.TunnelModeChildSessionParams.Builder#addInternalDnsServerRequest(int):
+ android.net.ipsec.ike.TunnelModeChildSessionParams does not declare a `getInternalDnsServerRequests()` method matching method android.net.ipsec.ike.TunnelModeChildSessionParams.Builder.addInternalDnsServerRequest(int)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.TunnelModeChildSessionParams.Builder#addOutboundTrafficSelectors(android.net.ipsec.ike.IkeTrafficSelector):
+ android.net.ipsec.ike.TunnelModeChildSessionParams does not declare a `getOutboundTrafficSelectorss()` method matching method android.net.ipsec.ike.TunnelModeChildSessionParams.Builder.addOutboundTrafficSelectors(android.net.ipsec.ike.IkeTrafficSelector)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.TunnelModeChildSessionParams.Builder#addSaProposal(android.net.ipsec.ike.ChildSaProposal):
+ android.net.ipsec.ike.TunnelModeChildSessionParams does not declare a `getSaProposals()` method matching method android.net.ipsec.ike.TunnelModeChildSessionParams.Builder.addSaProposal(android.net.ipsec.ike.ChildSaProposal)
+MissingGetterMatchingBuilder: android.net.ipsec.ike.TunnelModeChildSessionParams.Builder#setLifetimeSeconds(int, int):
+ android.net.ipsec.ike.TunnelModeChildSessionParams does not declare a `getLifetimeSeconds()` method matching method android.net.ipsec.ike.TunnelModeChildSessionParams.Builder.setLifetimeSeconds(int,int)
+
+
+MissingNullability: android.net.ipsec.ike.IkeSessionParams#getRetransmissionTimeoutsMillis():
+ Missing nullability on method `getRetransmissionTimeoutsMillis` return
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/IkeLocalRequestScheduler.java b/src/java/com/android/internal/net/ipsec/ike/IkeLocalRequestScheduler.java
index e86df23..f8008fb 100644
--- a/src/java/com/android/internal/net/ipsec/ike/IkeLocalRequestScheduler.java
+++ b/src/java/com/android/internal/net/ipsec/ike/IkeLocalRequestScheduler.java
@@ -64,15 +64,18 @@
* Notifies the scheduler that the caller is ready for a new procedure
*
* <p>Synchronously triggers the call to onNewProcedureReady.
+ *
+ * @return whether or not a new procedure was scheduled.
*/
- public void readyForNextProcedure() {
+ public boolean readyForNextProcedure() {
while (!mRequestQueue.isEmpty()) {
LocalRequest request = mRequestQueue.poll();
if (!request.isCancelled()) {
mConsumer.onNewProcedureReady(request);
- return;
+ return true;
}
}
+ return false;
}
/**
diff --git a/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java b/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java
index ec6d26a..ea496f8 100644
--- a/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java
+++ b/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java
@@ -22,6 +22,7 @@
import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_ADDITIONAL_SAS;
import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_TEMPORARY_FAILURE;
import static android.net.ipsec.ike.exceptions.IkeProtocolException.ErrorType;
+import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_TYPE_REPLY;
import static com.android.internal.net.ipsec.ike.message.IkeHeader.EXCHANGE_TYPE_INFORMATIONAL;
@@ -74,6 +75,7 @@
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.os.PowerManager;
import android.os.SystemClock;
import android.system.ErrnoException;
import android.system.Os;
@@ -365,6 +367,9 @@
*/
private final IpSecSpiGenerator mIpSecSpiGenerator;
+ /** Ensures that the system does not go to sleep in the middle of an exchange. */
+ private final PowerManager.WakeLock mBusyWakeLock;
+
@VisibleForTesting
@GuardedBy("mChildCbToSessions")
final HashMap<ChildSessionCallback, ChildSessionStateMachine> mChildCbToSessions =
@@ -492,6 +497,10 @@
// callback instance in the future
}
+ PowerManager pm = context.getSystemService(PowerManager.class);
+ mBusyWakeLock = pm.newWakeLock(PARTIAL_WAKE_LOCK, TAG + "mBusyWakeLock");
+ mBusyWakeLock.setReferenceCounted(false);
+
mIkeSessionId = sIkeSessionIdGenerator.getAndIncrement();
sIkeAlarmReceiver.registerIkeSession(mIkeSessionId, getHandler());
@@ -548,6 +557,7 @@
sendMessageAtFrontOfQueue(CMD_EXECUTE_LOCAL_REQ, localReq);
});
+ mBusyWakeLock.acquire();
start();
}
@@ -956,6 +966,8 @@
}
// TODO: Remove the stored ikeSessionCallback
}
+
+ mBusyWakeLock.release();
}
private void closeAllSaRecords(boolean expectSaClosed) {
@@ -1058,7 +1070,9 @@
@Override
public void enterState() {
- mScheduler.readyForNextProcedure();
+ if (!mScheduler.readyForNextProcedure()) {
+ mBusyWakeLock.release();
+ }
if (mDpdIntent == null) {
long remoteIkeSpi = mCurrentIkeSaRecord.getRemoteSpi();
@@ -1090,6 +1104,8 @@
// #exitState is guaranteed to be invoked when quit() or quitNow() is called
mAlarmManager.cancel(mDpdIntent);
logd("DPD Alarm canceled");
+
+ mBusyWakeLock.acquire();
}
@Override
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/AndroidManifest.xml b/tests/iketests/AndroidManifest.xml
index 0abddba..bdcfdb7 100644
--- a/tests/iketests/AndroidManifest.xml
+++ b/tests/iketests/AndroidManifest.xml
@@ -22,6 +22,8 @@
<uses-permission android:name="android.permission.INTERNET"/>
<!--Allow tests to call ConnectivityManager#getActiveNetwork()-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+ <!--Allow tests to use wake locks-->
+ <uses-permission android:name="android.permission.WAKE_LOCK"/>
<!--
'debuggable=true' is required to properly load mockito jvmti dependencies,
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachineTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachineTest.java
index 61f44e0..66c2517 100644
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachineTest.java
+++ b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachineTest.java
@@ -1196,6 +1196,7 @@
mLooper.dispatchAll();
verify(mSpyCurrentIkeSocket).releaseReference(eq(mIkeSessionStateMachine));
+ verify(mMockBusyWakelock).release();
}
@Test
@@ -1457,6 +1458,8 @@
/** Initializes the mIkeSessionStateMachine in the IDLE state. */
private void setupIdleStateMachine() throws Exception {
+ verify(mMockBusyWakelock).acquire();
+
setIkeInitResults();
mIkeSessionStateMachine.sendMessage(
@@ -1469,6 +1472,11 @@
assertTrue(
mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
+
+ verify(mMockBusyWakelock).release();
+
+ // For convenience to verify wakelocks in all other places.
+ reset(mMockBusyWakelock);
}
private void mockIkeInitAndTransitionToIkeAuth(State authState) throws Exception {
@@ -1630,6 +1638,7 @@
mIkeSessionStateMachine.getCurrentState()
instanceof IkeSessionStateMachine.ChildProcedureOngoing);
verify(mMockChildSessionStateMachine).deleteChildSession();
+ verify(mMockBusyWakelock).acquire();
}
@Test
@@ -1664,6 +1673,7 @@
mIkeSessionStateMachine.getCurrentState()
instanceof IkeSessionStateMachine.ChildProcedureOngoing);
verify(mMockChildSessionStateMachine).rekeyChildSession();
+ verify(mMockBusyWakelock).acquire();
}
@Test
@@ -1803,6 +1813,7 @@
List<IkePayload> payloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/);
assertEquals(1, payloadList.size());
assertEquals(outDelPayload, ((IkeDeletePayload) payloadList.get(0)));
+ verify(mMockBusyWakelock).acquire();
}
@Test
@@ -4108,6 +4119,7 @@
// Verify state machine quit properly
assertNull(mIkeSessionStateMachine.getCurrentState());
+ verify(mMockBusyWakelock).release();
}
@Test
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionTestBase.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionTestBase.java
index 174cd7c..e4e8379 100644
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionTestBase.java
+++ b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionTestBase.java
@@ -18,8 +18,11 @@
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
@@ -33,6 +36,7 @@
import android.net.NetworkCapabilities;
import android.net.SocketKeepalive;
import android.os.Handler;
+import android.os.PowerManager;
import com.android.internal.net.ipsec.ike.testutils.MockIpSecTestUtils;
import com.android.internal.net.ipsec.ike.utils.IkeAlarmReceiver;
@@ -50,9 +54,12 @@
(Inet4Address) (InetAddresses.parseNumericAddress("127.0.0.1"));
protected static final String REMOTE_HOSTNAME = "ike.test.android.com";
+ protected PowerManager.WakeLock mMockBusyWakelock;
+
protected MockIpSecTestUtils mMockIpSecTestUtils;
protected Context mSpyContext;
protected IpSecManager mIpSecManager;
+ protected PowerManager mPowerManager;
protected ConnectivityManager mMockConnectManager;
protected Network mMockDefaultNetwork;
@@ -74,6 +81,11 @@
any(Handler.class));
doNothing().when(mSpyContext).unregisterReceiver(any(IkeAlarmReceiver.class));
+ mPowerManager = mock(PowerManager.class);
+ mMockBusyWakelock = mock(PowerManager.WakeLock.class);
+ doReturn(mPowerManager).when(mSpyContext).getSystemService(eq(PowerManager.class));
+ doReturn(mMockBusyWakelock).when(mPowerManager).newWakeLock(anyInt(), anyString());
+
mMockConnectManager = mock(ConnectivityManager.class);
mMockDefaultNetwork = mock(Network.class);
doReturn(mMockDefaultNetwork).when(mMockConnectManager).getActiveNetwork();
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());
+ }
+}