Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a10003d5 authored by Nathan Harold's avatar Nathan Harold
Browse files

Input Validation for IpSecService

All of the input to IpSecService over the Binder
interface needs to be validated both for sanity
and for safety.

-Sanity check all the parameters coming from binder.
-Added setters for IpSecConfig to decouple the test
 from the IpSecManager. This was needed because the
 input validation caused the tests to fail due to a
 null parameter that was previously un-tested.
-Added the mode flag to the IpSecConfig bundle this
 oversight was found during testing.
-Expose the getResourceId() methods for testing in
 UdpEncapsulationSocket, SecurityParameterIndex, and
 IpSecTransform classes.
-Remove the unneeded getIpSecConfig() from
 IpSecTransform: unneeded now that we can synthesize
 configs.

Bug: 38397094
Test: runtest frameworks-net
Change-Id: I5241fc7fbfa9816d54219acd8d81a9f7eef10dd4
parent 1704df64
Loading
Loading
Loading
Loading
+145 −101
Original line number Diff line number Diff line
@@ -17,105 +17,163 @@ package android.net;

import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
import java.net.InetAddress;
import java.net.UnknownHostException;

import com.android.internal.annotations.VisibleForTesting;

/** @hide */
public final class IpSecConfig implements Parcelable {
    private static final String TAG = "IpSecConfig";

    // MODE_TRANSPORT or MODE_TUNNEL
    int mode;
    private int mMode = IpSecTransform.MODE_TRANSPORT;

    // For tunnel mode
    InetAddress localAddress;
    // Needs to be valid only for tunnel mode
    // Preventing this from being null simplifies Java->Native binder
    private String mLocalAddress = "";

    InetAddress remoteAddress;
    // Preventing this from being null simplifies Java->Native binder
    private String mRemoteAddress = "";

    // Limit selection by network interface
    Network network;
    // The underlying network interface that represents the "gateway" Network
    // for outbound packets. It may also be used to select packets.
    private Network mNetwork;

    public static class Flow {
        // Minimum requirements for identifying a transform
        // SPI identifying the IPsec flow in packet processing
        // and a remote IP address
        int spiResourceId;
        private int mSpiResourceId = IpSecManager.INVALID_RESOURCE_ID;

        // Encryption Algorithm
        IpSecAlgorithm encryption;
        private IpSecAlgorithm mEncryption;

        // Authentication Algorithm
        IpSecAlgorithm authentication;
        private IpSecAlgorithm mAuthentication;

        @Override
        public String toString() {
            return new StringBuilder()
                    .append("{spiResourceId=")
                    .append(spiResourceId)
                    .append(", encryption=")
                    .append(encryption)
                    .append(", authentication=")
                    .append(authentication)
                    .append("{mSpiResourceId=")
                    .append(mSpiResourceId)
                    .append(", mEncryption=")
                    .append(mEncryption)
                    .append(", mAuthentication=")
                    .append(mAuthentication)
                    .append("}")
                    .toString();
        }
    }

    final Flow[] flow = new Flow[] {new Flow(), new Flow()};
    private final Flow[] mFlow = new Flow[] {new Flow(), new Flow()};

    // For tunnel mode IPv4 UDP Encapsulation
    // IpSecTransform#ENCAP_ESP_*, such as ENCAP_ESP_OVER_UDP_IKE
    int encapType;
    int encapLocalPortResourceId;
    int encapRemotePort;
    private int mEncapType = IpSecTransform.ENCAP_NONE;
    private int mEncapSocketResourceId = IpSecManager.INVALID_RESOURCE_ID;
    private int mEncapRemotePort;

    // An interval, in seconds between the NattKeepalive packets
    int nattKeepaliveInterval;
    private int mNattKeepaliveInterval;

    /** Set the mode for this IPsec transform */
    public void setMode(int mode) {
        mMode = mode;
    }

    /** Set the local IP address for Tunnel mode */
    public void setLocalAddress(String localAddress) {
        if (localAddress == null) {
            throw new IllegalArgumentException("localAddress may not be null!");
        }
        mLocalAddress = localAddress;
    }

    /** Set the remote IP address for this IPsec transform */
    public void setRemoteAddress(String remoteAddress) {
        if (remoteAddress == null) {
            throw new IllegalArgumentException("remoteAddress may not be null!");
        }
        mRemoteAddress = remoteAddress;
    }

    /** Set the SPI for a given direction by resource ID */
    public void setSpiResourceId(int direction, int resourceId) {
        mFlow[direction].mSpiResourceId = resourceId;
    }

    /** Set the encryption algorithm for a given direction */
    public void setEncryption(int direction, IpSecAlgorithm encryption) {
        mFlow[direction].mEncryption = encryption;
    }

    /** Set the authentication algorithm for a given direction */
    public void setAuthentication(int direction, IpSecAlgorithm authentication) {
        mFlow[direction].mAuthentication = authentication;
    }

    public void setNetwork(Network network) {
        mNetwork = network;
    }

    public void setEncapType(int encapType) {
        mEncapType = encapType;
    }

    public void setEncapSocketResourceId(int resourceId) {
        mEncapSocketResourceId = resourceId;
    }

    public void setEncapRemotePort(int port) {
        mEncapRemotePort = port;
    }

    public void setNattKeepaliveInterval(int interval) {
        mNattKeepaliveInterval = interval;
    }

    // Transport or Tunnel
    public int getMode() {
        return mode;
        return mMode;
    }

    public InetAddress getLocalAddress() {
        return localAddress;
    public String getLocalAddress() {
        return mLocalAddress;
    }

    public int getSpiResourceId(int direction) {
        return flow[direction].spiResourceId;
        return mFlow[direction].mSpiResourceId;
    }

    public InetAddress getRemoteAddress() {
        return remoteAddress;
    public String getRemoteAddress() {
        return mRemoteAddress;
    }

    public IpSecAlgorithm getEncryption(int direction) {
        return flow[direction].encryption;
        return mFlow[direction].mEncryption;
    }

    public IpSecAlgorithm getAuthentication(int direction) {
        return flow[direction].authentication;
        return mFlow[direction].mAuthentication;
    }

    public Network getNetwork() {
        return network;
        return mNetwork;
    }

    public int getEncapType() {
        return encapType;
        return mEncapType;
    }

    public int getEncapLocalResourceId() {
        return encapLocalPortResourceId;
    public int getEncapSocketResourceId() {
        return mEncapSocketResourceId;
    }

    public int getEncapRemotePort() {
        return encapRemotePort;
        return mEncapRemotePort;
    }

    public int getNattKeepaliveInterval() {
        return nattKeepaliveInterval;
        return mNattKeepaliveInterval;
    }

    // Parcelable Methods
@@ -127,82 +185,68 @@ public final class IpSecConfig implements Parcelable {

    @Override
    public void writeToParcel(Parcel out, int flags) {
        // TODO: Use a byte array or other better method for storing IPs that can also include scope
        out.writeString((localAddress != null) ? localAddress.getHostAddress() : null);
        // TODO: Use a byte array or other better method for storing IPs that can also include scope
        out.writeString((remoteAddress != null) ? remoteAddress.getHostAddress() : null);
        out.writeParcelable(network, flags);
        out.writeInt(flow[IpSecTransform.DIRECTION_IN].spiResourceId);
        out.writeParcelable(flow[IpSecTransform.DIRECTION_IN].encryption, flags);
        out.writeParcelable(flow[IpSecTransform.DIRECTION_IN].authentication, flags);
        out.writeInt(flow[IpSecTransform.DIRECTION_OUT].spiResourceId);
        out.writeParcelable(flow[IpSecTransform.DIRECTION_OUT].encryption, flags);
        out.writeParcelable(flow[IpSecTransform.DIRECTION_OUT].authentication, flags);
        out.writeInt(encapType);
        out.writeInt(encapLocalPortResourceId);
        out.writeInt(encapRemotePort);
    }

    // Package Private: Used by the IpSecTransform.Builder;
    // there should be no public constructor for this object
    IpSecConfig() {}

    private static InetAddress readInetAddressFromParcel(Parcel in) {
        String addrString = in.readString();
        if (addrString == null) {
            return null;
        }
        try {
            return InetAddress.getByName(addrString);
        } catch (UnknownHostException e) {
            Log.wtf(TAG, "Invalid IpAddress " + addrString);
            return null;
        }
        out.writeInt(mMode);
        out.writeString(mLocalAddress);
        out.writeString(mRemoteAddress);
        out.writeParcelable(mNetwork, flags);
        out.writeInt(mFlow[IpSecTransform.DIRECTION_IN].mSpiResourceId);
        out.writeParcelable(mFlow[IpSecTransform.DIRECTION_IN].mEncryption, flags);
        out.writeParcelable(mFlow[IpSecTransform.DIRECTION_IN].mAuthentication, flags);
        out.writeInt(mFlow[IpSecTransform.DIRECTION_OUT].mSpiResourceId);
        out.writeParcelable(mFlow[IpSecTransform.DIRECTION_OUT].mEncryption, flags);
        out.writeParcelable(mFlow[IpSecTransform.DIRECTION_OUT].mAuthentication, flags);
        out.writeInt(mEncapType);
        out.writeInt(mEncapSocketResourceId);
        out.writeInt(mEncapRemotePort);
    }

    @VisibleForTesting
    public IpSecConfig() {}

    private IpSecConfig(Parcel in) {
        localAddress = readInetAddressFromParcel(in);
        remoteAddress = readInetAddressFromParcel(in);
        network = (Network) in.readParcelable(Network.class.getClassLoader());
        flow[IpSecTransform.DIRECTION_IN].spiResourceId = in.readInt();
        flow[IpSecTransform.DIRECTION_IN].encryption =
        mMode = in.readInt();
        mLocalAddress = in.readString();
        mRemoteAddress = in.readString();
        mNetwork = (Network) in.readParcelable(Network.class.getClassLoader());
        mFlow[IpSecTransform.DIRECTION_IN].mSpiResourceId = in.readInt();
        mFlow[IpSecTransform.DIRECTION_IN].mEncryption =
                (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
        flow[IpSecTransform.DIRECTION_IN].authentication =
        mFlow[IpSecTransform.DIRECTION_IN].mAuthentication =
                (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
        flow[IpSecTransform.DIRECTION_OUT].spiResourceId = in.readInt();
        flow[IpSecTransform.DIRECTION_OUT].encryption =
        mFlow[IpSecTransform.DIRECTION_OUT].mSpiResourceId = in.readInt();
        mFlow[IpSecTransform.DIRECTION_OUT].mEncryption =
                (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
        flow[IpSecTransform.DIRECTION_OUT].authentication =
        mFlow[IpSecTransform.DIRECTION_OUT].mAuthentication =
                (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
        encapType = in.readInt();
        encapLocalPortResourceId = in.readInt();
        encapRemotePort = in.readInt();
        mEncapType = in.readInt();
        mEncapSocketResourceId = in.readInt();
        mEncapRemotePort = in.readInt();
    }

    @Override
    public String toString() {
        StringBuilder strBuilder = new StringBuilder();
        strBuilder
                .append("{mode=")
                .append(mode == IpSecTransform.MODE_TUNNEL ? "TUNNEL" : "TRANSPORT")
                .append(", localAddress=")
                .append(localAddress)
                .append(", remoteAddress=")
                .append(remoteAddress)
                .append(", network=")
                .append(network)
                .append(", encapType=")
                .append(encapType)
                .append(", encapLocalPortResourceId=")
                .append(encapLocalPortResourceId)
                .append(", encapRemotePort=")
                .append(encapRemotePort)
                .append(", nattKeepaliveInterval=")
                .append(nattKeepaliveInterval)
                .append(", flow[OUT]=")
                .append(flow[IpSecTransform.DIRECTION_OUT])
                .append(", flow[IN]=")
                .append(flow[IpSecTransform.DIRECTION_IN])
                .append("{mMode=")
                .append(mMode == IpSecTransform.MODE_TUNNEL ? "TUNNEL" : "TRANSPORT")
                .append(", mLocalAddress=")
                .append(mLocalAddress)
                .append(", mRemoteAddress=")
                .append(mRemoteAddress)
                .append(", mNetwork=")
                .append(mNetwork)
                .append(", mEncapType=")
                .append(mEncapType)
                .append(", mEncapSocketResourceId=")
                .append(mEncapSocketResourceId)
                .append(", mEncapRemotePort=")
                .append(mEncapRemotePort)
                .append(", mNattKeepaliveInterval=")
                .append(mNattKeepaliveInterval)
                .append(", mFlow[OUT]=")
                .append(mFlow[IpSecTransform.DIRECTION_OUT])
                .append(", mFlow[IN]=")
                .append(mFlow[IpSecTransform.DIRECTION_IN])
                .append("}");

        return strBuilder.toString();
+6 −2
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@ import android.os.RemoteException;
import android.util.AndroidException;
import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;

import dalvik.system.CloseGuard;

import java.io.FileDescriptor;
@@ -188,7 +190,8 @@ public final class IpSecManager {
        }

        /** @hide */
        int getResourceId() {
        @VisibleForTesting
        public int getResourceId() {
            return mResourceId;
        }
    }
@@ -489,7 +492,8 @@ public final class IpSecManager {
        }

        /** @hide */
        int getResourceId() {
        @VisibleForTesting
        public int getResourceId() {
            return mResourceId;
        }
    };
+27 −76
Original line number Diff line number Diff line
@@ -68,10 +68,10 @@ public final class IpSecTransform implements AutoCloseable {
    public @interface TransformDirection {}

    /** @hide */
    public static final int MODE_TUNNEL = 0;
    public static final int MODE_TRANSPORT = 0;

    /** @hide */
    public static final int MODE_TRANSPORT = 1;
    public static final int MODE_TUNNEL = 1;

    /** @hide */
    public static final int ENCAP_NONE = 0;
@@ -113,7 +113,11 @@ public final class IpSecTransform implements AutoCloseable {
        return IIpSecService.Stub.asInterface(b);
    }

    private void checkResultStatusAndThrow(int status)
    /**
     * Checks the result status and throws an appropriate exception if
     * the status is not Status.OK.
     */
    private void checkResultStatus(int status)
            throws IOException, IpSecManager.ResourceUnavailableException,
                    IpSecManager.SpiUnavailableException {
        switch (status) {
@@ -141,7 +145,7 @@ public final class IpSecTransform implements AutoCloseable {
                IpSecTransformResponse result =
                        svc.createTransportModeTransform(mConfig, new Binder());
                int status = result.status;
                checkResultStatusAndThrow(status);
                checkResultStatus(status);
                mResourceId = result.resourceId;

                /* Keepalive will silently fail if not needed by the config; but, if needed and
@@ -243,62 +247,21 @@ public final class IpSecTransform implements AutoCloseable {

    /* Package */
    void startKeepalive(Context c) {
        // FIXME: NO_KEEPALIVE needs to be a constant
        if (mConfig.getNattKeepaliveInterval() == 0) {
            return;
        if (mConfig.getNattKeepaliveInterval() != 0) {
            Log.wtf(TAG, "Keepalive not yet supported.");
        }

        ConnectivityManager cm =
                (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE);

        if (mKeepalive != null) {
            Log.wtf(TAG, "Keepalive already started for this IpSecTransform.");
            return;
    }

        synchronized (mKeepaliveSyncLock) {
            mKeepalive =
                    cm.startNattKeepalive(
                            mConfig.getNetwork(),
                            mConfig.getNattKeepaliveInterval(),
                            mKeepaliveCallback,
                            mConfig.getLocalAddress(),
                            0x1234, /* FIXME: get the real port number again,
                                    which we need to retrieve from the provided
                                    EncapsulationSocket, and which isn't currently
                                    stashed in IpSecConfig */
                            mConfig.getRemoteAddress());
            try {
                // FIXME: this is still a horrible way to fudge the synchronous callback
                mKeepaliveSyncLock.wait(2000);
            } catch (InterruptedException e) {
            }
        }
        if (mKeepaliveStatus != ConnectivityManager.PacketKeepalive.SUCCESS) {
            throw new UnsupportedOperationException("Packet Keepalive cannot be started");
        }
    }

    /* Package */
    int getResourceId() {
    /** @hide */
    @VisibleForTesting
    public int getResourceId() {
        return mResourceId;
    }

    /* Package */
    void stopKeepalive() {
        if (mKeepalive == null) {
        return;
    }
        mKeepalive.stop();
        synchronized (mKeepaliveSyncLock) {
            if (mKeepaliveStatus == ConnectivityManager.PacketKeepalive.SUCCESS) {
                try {
                    mKeepaliveSyncLock.wait(2000);
                } catch (InterruptedException e) {
                }
            }
        }
    }

    /**
     * Builder object to facilitate the creation of IpSecTransform objects.
@@ -323,7 +286,7 @@ public final class IpSecTransform implements AutoCloseable {
         */
        public IpSecTransform.Builder setEncryption(
                @TransformDirection int direction, IpSecAlgorithm algo) {
            mConfig.flow[direction].encryption = algo;
            mConfig.setEncryption(direction, algo);
            return this;
        }

@@ -338,7 +301,7 @@ public final class IpSecTransform implements AutoCloseable {
         */
        public IpSecTransform.Builder setAuthentication(
                @TransformDirection int direction, IpSecAlgorithm algo) {
            mConfig.flow[direction].authentication = algo;
            mConfig.setAuthentication(direction, algo);
            return this;
        }

@@ -361,9 +324,7 @@ public final class IpSecTransform implements AutoCloseable {
         */
        public IpSecTransform.Builder setSpi(
                @TransformDirection int direction, IpSecManager.SecurityParameterIndex spi) {
            // TODO: convert to using the resource Id of the SPI. Then build() can validate
            // the owner in the IpSecService
            mConfig.flow[direction].spiResourceId = spi.getResourceId();
            mConfig.setSpiResourceId(direction, spi.getResourceId());
            return this;
        }

@@ -378,7 +339,7 @@ public final class IpSecTransform implements AutoCloseable {
         */
        @SystemApi
        public IpSecTransform.Builder setUnderlyingNetwork(Network net) {
            mConfig.network = net;
            mConfig.setNetwork(net);
            return this;
        }

@@ -395,10 +356,9 @@ public final class IpSecTransform implements AutoCloseable {
         */
        public IpSecTransform.Builder setIpv4Encapsulation(
                IpSecManager.UdpEncapsulationSocket localSocket, int remotePort) {
            // TODO: check encap type is valid.
            mConfig.encapType = ENCAP_ESPINUDP;
            mConfig.encapLocalPortResourceId = localSocket.getResourceId();
            mConfig.encapRemotePort = remotePort;
            mConfig.setEncapType(ENCAP_ESPINUDP);
            mConfig.setEncapSocketResourceId(localSocket.getResourceId());
            mConfig.setEncapRemotePort(remotePort);
            return this;
        }

@@ -416,7 +376,7 @@ public final class IpSecTransform implements AutoCloseable {
         */
        @SystemApi
        public IpSecTransform.Builder setNattKeepalive(int intervalSeconds) {
            mConfig.nattKeepaliveInterval = intervalSeconds;
            mConfig.setNattKeepaliveInterval(intervalSeconds);
            return this;
        }

@@ -451,8 +411,8 @@ public final class IpSecTransform implements AutoCloseable {
                        IpSecManager.SpiUnavailableException, IOException {
            //FIXME: argument validation here
            //throw new IllegalArgumentException("Natt Keepalive requires UDP Encapsulation");
            mConfig.mode = MODE_TRANSPORT;
            mConfig.remoteAddress = remoteAddress;
            mConfig.setMode(MODE_TRANSPORT);
            mConfig.setRemoteAddress(remoteAddress.getHostAddress());
            return new IpSecTransform(mContext, mConfig).activate();
        }

@@ -473,9 +433,9 @@ public final class IpSecTransform implements AutoCloseable {
                InetAddress localAddress, InetAddress remoteAddress) {
            //FIXME: argument validation here
            //throw new IllegalArgumentException("Natt Keepalive requires UDP Encapsulation");
            mConfig.localAddress = localAddress;
            mConfig.remoteAddress = remoteAddress;
            mConfig.mode = MODE_TUNNEL;
            mConfig.setLocalAddress(localAddress.getHostAddress());
            mConfig.setRemoteAddress(remoteAddress.getHostAddress());
            mConfig.setMode(MODE_TUNNEL);
            return new IpSecTransform(mContext, mConfig);
        }

@@ -489,14 +449,5 @@ public final class IpSecTransform implements AutoCloseable {
            mContext = context;
            mConfig = new IpSecConfig();
        }

        /**
         * Return an {@link IpSecConfig} object for testing purposes.
         * @hide
         */
        @VisibleForTesting
        public IpSecConfig getIpSecConfig() {
            return mConfig;
        }
    }
}
+122 −29

File changed.

Preview size limit exceeded, changes collapsed.

+35 −16
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
@@ -297,24 +296,23 @@ public class IpSecServiceTest {
        IpSecAlgorithm authAlgo =
                new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 8);

        InetAddress localAddr = InetAddress.getByAddress(new byte[] {127, 0, 0, 1});

        InetAddress remoteAddr = InetAddress.getByName("8.8.4.4");
        /** Allocate and add SPI records in the IpSecService through IpSecManager interface. */
        IpSecManager.SecurityParameterIndex outSpi =
                ipSecManager.reserveSecurityParameterIndex(IpSecTransform.DIRECTION_OUT, localAddr);
                ipSecManager.reserveSecurityParameterIndex(
                        IpSecTransform.DIRECTION_OUT, remoteAddr);
        IpSecManager.SecurityParameterIndex inSpi =
                ipSecManager.reserveSecurityParameterIndex(IpSecTransform.DIRECTION_IN, localAddr);

        IpSecConfig ipSecConfig =
                new IpSecTransform.Builder(mMockContext)
                        .setSpi(IpSecTransform.DIRECTION_OUT, outSpi)
                        .setSpi(IpSecTransform.DIRECTION_IN, inSpi)
                        .setEncryption(IpSecTransform.DIRECTION_OUT, encryptAlgo)
                        .setAuthentication(IpSecTransform.DIRECTION_OUT, authAlgo)
                        .setEncryption(IpSecTransform.DIRECTION_IN, encryptAlgo)
                        .setAuthentication(IpSecTransform.DIRECTION_IN, authAlgo)
                        .getIpSecConfig();
        return ipSecConfig;
                ipSecManager.reserveSecurityParameterIndex(IpSecTransform.DIRECTION_IN, remoteAddr);

        IpSecConfig config = new IpSecConfig();
        config.setSpiResourceId(IpSecTransform.DIRECTION_IN, inSpi.getResourceId());
        config.setSpiResourceId(IpSecTransform.DIRECTION_OUT, outSpi.getResourceId());
        config.setEncryption(IpSecTransform.DIRECTION_OUT, encryptAlgo);
        config.setAuthentication(IpSecTransform.DIRECTION_OUT, authAlgo);
        config.setEncryption(IpSecTransform.DIRECTION_IN, encryptAlgo);
        config.setAuthentication(IpSecTransform.DIRECTION_IN, authAlgo);
        config.setRemoteAddress(remoteAddr.getHostName());
        return config;
    }

    @Test
@@ -432,4 +430,25 @@ public class IpSecServiceTest {

        verify(mMockNetd).ipSecRemoveTransportModeTransform(pfd.getFileDescriptor());
    }

    @Test
    public void testValidateIpAddresses() throws Exception {
        String[] invalidAddresses =
                new String[] {"www.google.com", "::", "2001::/64", "0.0.0.0", ""};
        for (String address : invalidAddresses) {
            try {
                IpSecSpiResponse spiResp =
                        mIpSecService.reserveSecurityParameterIndex(
                                IpSecTransform.DIRECTION_OUT, address, DROID_SPI, new Binder());
                fail("Invalid address was passed through IpSecService validation: " + address);
            } catch (IllegalArgumentException e) {
            } catch (Exception e) {
                fail(
                        "Invalid InetAddress was not caught in validation: "
                                + address
                                + ", Exception: "
                                + e);
            }
        }
    }
}