diff options
| author | Nathan Harold <nharold@google.com> | 2017-08-23 13:46:33 -0700 |
|---|---|---|
| committer | Nathan Harold <nharold@google.com> | 2017-10-03 19:45:55 -0700 |
| commit | a10003d5de52339f4d30fedd7294941378e5f13c (patch) | |
| tree | 2ec4a2c155a9b379aa330905c0e04ca61df2780e /core/java/android/net/IpSecConfig.java | |
| parent | 1704df64ceaa282c8f91f886204261af1f4395a2 (diff) | |
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
Diffstat (limited to 'core/java/android/net/IpSecConfig.java')
| -rw-r--r-- | core/java/android/net/IpSecConfig.java | 246 |
1 files changed, 145 insertions, 101 deletions
diff --git a/core/java/android/net/IpSecConfig.java b/core/java/android/net/IpSecConfig.java index 5a5c740c7aa8..56224afc277c 100644 --- a/core/java/android/net/IpSecConfig.java +++ b/core/java/android/net/IpSecConfig.java @@ -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; + // MODE_TRANSPORT or MODE_TUNNEL + 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(); |
