IpSecManager.java revision 5a920ca377efaaaaabf3fe6c77111d8158202055
1330e1089da80cddcd68758512370d217b19f8890Nathan Harold/* 2330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Copyright (C) 2017 The Android Open Source Project 3330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 4330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Licensed under the Apache License, Version 2.0 (the "License"); 5330e1089da80cddcd68758512370d217b19f8890Nathan Harold * you may not use this file except in compliance with the License. 6330e1089da80cddcd68758512370d217b19f8890Nathan Harold * You may obtain a copy of the License at 7330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 8330e1089da80cddcd68758512370d217b19f8890Nathan Harold * http://www.apache.org/licenses/LICENSE-2.0 9330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 10330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Unless required by applicable law or agreed to in writing, software 11330e1089da80cddcd68758512370d217b19f8890Nathan Harold * distributed under the License is distributed on an "AS IS" BASIS, 12330e1089da80cddcd68758512370d217b19f8890Nathan Harold * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13330e1089da80cddcd68758512370d217b19f8890Nathan Harold * See the License for the specific language governing permissions and 14330e1089da80cddcd68758512370d217b19f8890Nathan Harold * limitations under the License. 15330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 16330e1089da80cddcd68758512370d217b19f8890Nathan Haroldpackage android.net; 17330e1089da80cddcd68758512370d217b19f8890Nathan Harold 18330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport static com.android.internal.util.Preconditions.checkNotNull; 19330e1089da80cddcd68758512370d217b19f8890Nathan Harold 20a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Haroldimport android.annotation.IntDef; 2193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Haroldimport android.annotation.NonNull; 225a920ca377efaaaaabf3fe6c77111d8158202055Nathan Haroldimport android.annotation.RequiresPermission; 23c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Haroldimport android.annotation.SystemApi; 24d86b8fea43ebb6e5c31691b44d8ceb0d8d3c9072Jeff Sharkeyimport android.annotation.SystemService; 25c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseriimport android.annotation.TestApi; 26d86b8fea43ebb6e5c31691b44d8ceb0d8d3c9072Jeff Sharkeyimport android.content.Context; 2793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Haroldimport android.os.Binder; 28330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport android.os.ParcelFileDescriptor; 2993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Haroldimport android.os.RemoteException; 30330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport android.util.AndroidException; 318dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Haroldimport android.util.Log; 32b72821747cd8cfa9bcaff7f11247ebfce3255fbfNathan Harold 33a10003d5de52339f4d30fedd7294941378e5f13cNathan Haroldimport com.android.internal.annotations.VisibleForTesting; 34a10003d5de52339f4d30fedd7294941378e5f13cNathan Harold 35330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport dalvik.system.CloseGuard; 36b72821747cd8cfa9bcaff7f11247ebfce3255fbfNathan Harold 37330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.io.FileDescriptor; 38330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.io.IOException; 39a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Haroldimport java.lang.annotation.Retention; 40a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Haroldimport java.lang.annotation.RetentionPolicy; 41330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.net.DatagramSocket; 42330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.net.InetAddress; 43330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.net.Socket; 44330e1089da80cddcd68758512370d217b19f8890Nathan Harold 45330e1089da80cddcd68758512370d217b19f8890Nathan Harold/** 46c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * This class contains methods for managing IPsec sessions. Once configured, the kernel will apply 47c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * confidentiality (encryption) and integrity (authentication) to IP traffic. 48330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 49c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * <p>Note that not all aspects of IPsec are permitted by this API. Applications may create 50c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * transport mode security associations and apply them to individual sockets. Applications looking 51c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * to create a VPN should use {@link VpnService}. 52c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * 53c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * @see <a href="https://tools.ietf.org/html/rfc4301">RFC 4301, Security Architecture for the 545fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * Internet Protocol</a> 55330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 56d86b8fea43ebb6e5c31691b44d8ceb0d8d3c9072Jeff Sharkey@SystemService(Context.IPSEC_SERVICE) 57330e1089da80cddcd68758512370d217b19f8890Nathan Haroldpublic final class IpSecManager { 58330e1089da80cddcd68758512370d217b19f8890Nathan Harold private static final String TAG = "IpSecManager"; 59330e1089da80cddcd68758512370d217b19f8890Nathan Harold 60330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 61a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold * For direction-specific attributes of an {@link IpSecTransform}, indicates that an attribute 62a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold * applies to traffic towards the host. 63a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold */ 64a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold public static final int DIRECTION_IN = 0; 65a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold 66a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold /** 67a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold * For direction-specific attributes of an {@link IpSecTransform}, indicates that an attribute 68a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold * applies to traffic from the host. 69a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold */ 70a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold public static final int DIRECTION_OUT = 1; 71a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold 72a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold /** @hide */ 73a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold @IntDef(value = {DIRECTION_IN, DIRECTION_OUT}) 74a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold @Retention(RetentionPolicy.SOURCE) 75a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold public @interface PolicyDirection {} 76a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold 77a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold /** 78c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * The Security Parameter Index (SPI) 0 indicates an unknown or invalid index. 7993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold * 8093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold * <p>No IPsec packet may contain an SPI of 0. 81c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * 82c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * @hide 8393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold */ 845fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri @TestApi public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; 8593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold 8693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold /** @hide */ 8793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold public interface Status { 8893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold public static final int OK = 0; 8993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold public static final int RESOURCE_UNAVAILABLE = 1; 9093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold public static final int SPI_UNAVAILABLE = 2; 9193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 9293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold 9393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold /** @hide */ 946119d8d1d0d89b0d4c4ac822e9e93bb47f1ebd9aNathan Harold public static final int INVALID_RESOURCE_ID = -1; 9593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold 9693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold /** 97c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * Thrown to indicate that a requested SPI is in use. 98c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * 99c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * <p>The combination of remote {@code InetAddress} and SPI must be unique across all apps on 100c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * one device. If this error is encountered, a new SPI is required before a transform may be 101c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * created. This error can be avoided by calling {@link 1025fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * IpSecManager#allocateSecurityParameterIndex}. 103330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 104330e1089da80cddcd68758512370d217b19f8890Nathan Harold public static final class SpiUnavailableException extends AndroidException { 105330e1089da80cddcd68758512370d217b19f8890Nathan Harold private final int mSpi; 106330e1089da80cddcd68758512370d217b19f8890Nathan Harold 107330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 108330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Construct an exception indicating that a transform with the given SPI is already in use 109330e1089da80cddcd68758512370d217b19f8890Nathan Harold * or otherwise unavailable. 110330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 111c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * @param msg description indicating the colliding SPI 112330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param spi the SPI that could not be used due to a collision 113330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 114330e1089da80cddcd68758512370d217b19f8890Nathan Harold SpiUnavailableException(String msg, int spi) { 115c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri super(msg + " (spi: " + spi + ")"); 116330e1089da80cddcd68758512370d217b19f8890Nathan Harold mSpi = spi; 117330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 118330e1089da80cddcd68758512370d217b19f8890Nathan Harold 119c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri /** Get the SPI that caused a collision. */ 120330e1089da80cddcd68758512370d217b19f8890Nathan Harold public int getSpi() { 121330e1089da80cddcd68758512370d217b19f8890Nathan Harold return mSpi; 122330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 123330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 124330e1089da80cddcd68758512370d217b19f8890Nathan Harold 125330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 126c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * Thrown to indicate that an IPsec resource is unavailable. 127c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * 128c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * <p>This could apply to resources such as sockets, {@link SecurityParameterIndex}, {@link 129c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * IpSecTransform}, or other system resources. If this exception is thrown, users should release 130c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * allocated objects of the type requested. 131330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 132330e1089da80cddcd68758512370d217b19f8890Nathan Harold public static final class ResourceUnavailableException extends AndroidException { 133330e1089da80cddcd68758512370d217b19f8890Nathan Harold 134330e1089da80cddcd68758512370d217b19f8890Nathan Harold ResourceUnavailableException(String msg) { 135330e1089da80cddcd68758512370d217b19f8890Nathan Harold super(msg); 136330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 137330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 138330e1089da80cddcd68758512370d217b19f8890Nathan Harold 1391afbef40c68373f3871eed087c546cfe1911ee36Nathan Harold private final IIpSecService mService; 140330e1089da80cddcd68758512370d217b19f8890Nathan Harold 141c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri /** 142c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * This class represents a reserved SPI. 143c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * 144c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * <p>Objects of this type are used to track reserved security parameter indices. They can be 1455fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * obtained by calling {@link IpSecManager#allocateSecurityParameterIndex} and must be released 146c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * by calling {@link #close()} when they are no longer needed. 147c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri */ 148330e1089da80cddcd68758512370d217b19f8890Nathan Harold public static final class SecurityParameterIndex implements AutoCloseable { 1491afbef40c68373f3871eed087c546cfe1911ee36Nathan Harold private final IIpSecService mService; 150a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold private final InetAddress mDestinationAddress; 151330e1089da80cddcd68758512370d217b19f8890Nathan Harold private final CloseGuard mCloseGuard = CloseGuard.get(); 15293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold private int mSpi = INVALID_SECURITY_PARAMETER_INDEX; 1536119d8d1d0d89b0d4c4ac822e9e93bb47f1ebd9aNathan Harold private int mResourceId = INVALID_RESOURCE_ID; 154330e1089da80cddcd68758512370d217b19f8890Nathan Harold 155c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri /** Get the underlying SPI held by this object. */ 156330e1089da80cddcd68758512370d217b19f8890Nathan Harold public int getSpi() { 157330e1089da80cddcd68758512370d217b19f8890Nathan Harold return mSpi; 158330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 159330e1089da80cddcd68758512370d217b19f8890Nathan Harold 160330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 161330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Release an SPI that was previously reserved. 162330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 163c4f879925b58b1b5ca9a3cfdc898c20cbf56355aNathan Harold * <p>Release an SPI for use by other users in the system. If a SecurityParameterIndex is 164c4f879925b58b1b5ca9a3cfdc898c20cbf56355aNathan Harold * applied to an IpSecTransform, it will become unusable for future transforms but should 165c4f879925b58b1b5ca9a3cfdc898c20cbf56355aNathan Harold * still be closed to ensure system resources are released. 166330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 167330e1089da80cddcd68758512370d217b19f8890Nathan Harold @Override 168330e1089da80cddcd68758512370d217b19f8890Nathan Harold public void close() { 1698dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold try { 1708dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold mService.releaseSecurityParameterIndex(mResourceId); 1716119d8d1d0d89b0d4c4ac822e9e93bb47f1ebd9aNathan Harold mResourceId = INVALID_RESOURCE_ID; 1728dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } catch (RemoteException e) { 1738dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold throw e.rethrowFromSystemServer(); 1748dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 175330e1089da80cddcd68758512370d217b19f8890Nathan Harold mCloseGuard.close(); 176330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 177330e1089da80cddcd68758512370d217b19f8890Nathan Harold 178c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri /** Check that the SPI was closed properly. */ 179330e1089da80cddcd68758512370d217b19f8890Nathan Harold @Override 180440824f7434e1e2c343b21a9ca3e6f405b8e0ea1Nathan Harold protected void finalize() throws Throwable { 181330e1089da80cddcd68758512370d217b19f8890Nathan Harold if (mCloseGuard != null) { 182330e1089da80cddcd68758512370d217b19f8890Nathan Harold mCloseGuard.warnIfOpen(); 183330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 184330e1089da80cddcd68758512370d217b19f8890Nathan Harold 185330e1089da80cddcd68758512370d217b19f8890Nathan Harold close(); 186330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 187330e1089da80cddcd68758512370d217b19f8890Nathan Harold 18893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold private SecurityParameterIndex( 189a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold @NonNull IIpSecService service, InetAddress destinationAddress, int spi) 19093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold throws ResourceUnavailableException, SpiUnavailableException { 19193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold mService = service; 192a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold mDestinationAddress = destinationAddress; 19393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold try { 1948dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold IpSecSpiResponse result = 1955fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri mService.allocateSecurityParameterIndex( 196a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold destinationAddress.getHostAddress(), spi, new Binder()); 19793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold 19893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold if (result == null) { 19993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold throw new NullPointerException("Received null response from IpSecService"); 20093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 20193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold 2028dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold int status = result.status; 20393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold switch (status) { 20493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold case Status.OK: 20593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold break; 20693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold case Status.RESOURCE_UNAVAILABLE: 20793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold throw new ResourceUnavailableException( 20893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold "No more SPIs may be allocated by this requester."); 20993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold case Status.SPI_UNAVAILABLE: 21093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold throw new SpiUnavailableException("Requested SPI is unavailable", spi); 21193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold default: 21293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold throw new RuntimeException( 21393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold "Unknown status returned by IpSecService: " + status); 21493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 2158dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold mSpi = result.spi; 2168dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold mResourceId = result.resourceId; 21793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold 21893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold if (mSpi == INVALID_SECURITY_PARAMETER_INDEX) { 21993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold throw new RuntimeException("Invalid SPI returned by IpSecService: " + status); 22093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 22193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold 22293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold if (mResourceId == INVALID_RESOURCE_ID) { 22393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold throw new RuntimeException( 22493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold "Invalid Resource ID returned by IpSecService: " + status); 22593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 22693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold 22793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } catch (RemoteException e) { 22893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold throw e.rethrowFromSystemServer(); 22993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 23093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold mCloseGuard.open("open"); 23193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 2328dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold 2338dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold /** @hide */ 234a10003d5de52339f4d30fedd7294941378e5f13cNathan Harold @VisibleForTesting 235a10003d5de52339f4d30fedd7294941378e5f13cNathan Harold public int getResourceId() { 2368dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold return mResourceId; 2378dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 23893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 239330e1089da80cddcd68758512370d217b19f8890Nathan Harold 240330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 241a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold * Reserve a random SPI for traffic bound to or from the specified destination address. 242330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 243330e1089da80cddcd68758512370d217b19f8890Nathan Harold * <p>If successful, this SPI is guaranteed available until released by a call to {@link 244330e1089da80cddcd68758512370d217b19f8890Nathan Harold * SecurityParameterIndex#close()}. 245330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 246a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold * @param destinationAddress the destination address for traffic bearing the requested SPI. 247a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold * For inbound traffic, the destination should be an address currently assigned on-device. 248330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @return the reserved SecurityParameterIndex 249a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold * @throws {@link #ResourceUnavailableException} indicating that too many SPIs are 250a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold * currently allocated for this user 251330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 252a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold public SecurityParameterIndex allocateSecurityParameterIndex(InetAddress destinationAddress) 253a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold throws ResourceUnavailableException { 2546045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold try { 2556045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold return new SecurityParameterIndex( 2566045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold mService, 257a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold destinationAddress, 2586045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold IpSecManager.INVALID_SECURITY_PARAMETER_INDEX); 2596045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold } catch (SpiUnavailableException unlikely) { 2606045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold throw new ResourceUnavailableException("No SPIs available"); 2616045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold } 2626045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold } 2636045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold 2646045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold /** 265a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold * Reserve the requested SPI for traffic bound to or from the specified destination address. 2666045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold * 2676045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold * <p>If successful, this SPI is guaranteed available until released by a call to {@link 2686045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold * SecurityParameterIndex#close()}. 2696045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold * 270a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold * @param destinationAddress the destination address for traffic bearing the requested SPI. 271a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold * For inbound traffic, the destination should be an address currently assigned on-device. 272c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * @param requestedSpi the requested SPI, or '0' to allocate a random SPI 2736045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold * @return the reserved SecurityParameterIndex 274a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold * @throws {@link #ResourceUnavailableException} indicating that too many SPIs are 275a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold * currently allocated for this user 276a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold * @throws {@link #SpiUnavailableException} indicating that the requested SPI could not be 277a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold * reserved 2786045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold */ 2795fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri public SecurityParameterIndex allocateSecurityParameterIndex( 280a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold InetAddress destinationAddress, int requestedSpi) 281330e1089da80cddcd68758512370d217b19f8890Nathan Harold throws SpiUnavailableException, ResourceUnavailableException { 2826045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold if (requestedSpi == IpSecManager.INVALID_SECURITY_PARAMETER_INDEX) { 2836045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold throw new IllegalArgumentException("Requested SPI must be a valid (non-zero) SPI"); 2846045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold } 285a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold return new SecurityParameterIndex(mService, destinationAddress, requestedSpi); 286330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 287330e1089da80cddcd68758512370d217b19f8890Nathan Harold 288330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 289c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * Apply an IPsec transform to a stream socket. 290c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * 291c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * <p>This applies transport mode encapsulation to the given socket. Once applied, I/O on the 292c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * socket will be encapsulated according to the parameters of the {@code IpSecTransform}. When 293a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold * the transform is removed from the socket by calling {@link #removeTransportModeTransforms}, 294c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * unprotected traffic can resume on that socket. 295c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * 296c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * <p>For security reasons, the destination address of any traffic on the socket must match the 2975fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * remote {@code InetAddress} of the {@code IpSecTransform}. Attempts to send traffic to any 298c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * other IP address will result in an IOException. In addition, reads and writes on the socket 299c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * will throw IOException if the user deactivates the transform (by calling {@link 300a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold * IpSecTransform#close()}) without calling {@link #removeTransportModeTransforms}. 301c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * 3025fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * <h4>Rekey Procedure</h4> 3035fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * 3045fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * <p>When applying a new tranform to a socket, the previous transform will be removed. However, 3055fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * inbound traffic on the old transform will continue to be decrypted until that transform is 3065fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * deallocated by calling {@link IpSecTransform#close()}. This overlap allows rekey procedures 3075fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * where both transforms are valid until both endpoints are using the new transform and all 3085fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * in-flight packets have been received. 309330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 310330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param socket a stream socket 311a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold * @param direction the policy direction either {@link #DIRECTION_IN} or {@link #DIRECTION_OUT} 312c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * @param transform a transport mode {@code IpSecTransform} 313c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * @throws IOException indicating that the transform could not be applied 314330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 315a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold public void applyTransportModeTransform( 316a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold Socket socket, int direction, IpSecTransform transform) 317330e1089da80cddcd68758512370d217b19f8890Nathan Harold throws IOException { 318b548d251b7995a5b76e495978b61ad6c3c4183d1Nathan Harold applyTransportModeTransform(socket.getFileDescriptor$(), direction, transform); 319330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 320330e1089da80cddcd68758512370d217b19f8890Nathan Harold 321330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 322c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * Apply an IPsec transform to a datagram socket. 323c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * 324c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * <p>This applies transport mode encapsulation to the given socket. Once applied, I/O on the 325c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * socket will be encapsulated according to the parameters of the {@code IpSecTransform}. When 326a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold * the transform is removed from the socket by calling {@link #removeTransportModeTransforms}, 327c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * unprotected traffic can resume on that socket. 328c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * 329c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * <p>For security reasons, the destination address of any traffic on the socket must match the 330c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * remote {@code InetAddress} of the {@code IpSecTransform}. Attempts to send traffic to any 331c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * other IP address will result in an IOException. In addition, reads and writes on the socket 332c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * will throw IOException if the user deactivates the transform (by calling {@link 333a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold * IpSecTransform#close()}) without calling {@link #removeTransportModeTransforms}. 334c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * 3355fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * <h4>Rekey Procedure</h4> 3365fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * 3375fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * <p>When applying a new tranform to a socket, the previous transform will be removed. However, 3385fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * inbound traffic on the old transform will continue to be decrypted until that transform is 3395fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * deallocated by calling {@link IpSecTransform#close()}. This overlap allows rekey procedures 3405fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * where both transforms are valid until both endpoints are using the new transform and all 3415fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * in-flight packets have been received. 342330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 343330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param socket a datagram socket 344a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold * @param direction the policy direction either DIRECTION_IN or DIRECTION_OUT 345c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * @param transform a transport mode {@code IpSecTransform} 346c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * @throws IOException indicating that the transform could not be applied 347330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 348a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold public void applyTransportModeTransform( 349a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold DatagramSocket socket, int direction, IpSecTransform transform) throws IOException { 350b548d251b7995a5b76e495978b61ad6c3c4183d1Nathan Harold applyTransportModeTransform(socket.getFileDescriptor$(), direction, transform); 35193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 352330e1089da80cddcd68758512370d217b19f8890Nathan Harold 353330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 354c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * Apply an IPsec transform to a socket. 355c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * 356c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * <p>This applies transport mode encapsulation to the given socket. Once applied, I/O on the 357c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * socket will be encapsulated according to the parameters of the {@code IpSecTransform}. When 358a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold * the transform is removed from the socket by calling {@link #removeTransportModeTransforms}, 359c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * unprotected traffic can resume on that socket. 360c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * 361c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * <p>For security reasons, the destination address of any traffic on the socket must match the 362c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * remote {@code InetAddress} of the {@code IpSecTransform}. Attempts to send traffic to any 363c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * other IP address will result in an IOException. In addition, reads and writes on the socket 364c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * will throw IOException if the user deactivates the transform (by calling {@link 365a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold * IpSecTransform#close()}) without calling {@link #removeTransportModeTransforms}. 366c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * 3675fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * <h4>Rekey Procedure</h4> 3685fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * 3695fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * <p>When applying a new tranform to a socket, the previous transform will be removed. However, 3705fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * inbound traffic on the old transform will continue to be decrypted until that transform is 3715fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * deallocated by calling {@link IpSecTransform#close()}. This overlap allows rekey procedures 3725fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * where both transforms are valid until both endpoints are using the new transform and all 3735fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * in-flight packets have been received. 374b64993559b049327365bb63e81e8046a892a1033Nathan Harold * 375b64993559b049327365bb63e81e8046a892a1033Nathan Harold * @param socket a socket file descriptor 376a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold * @param direction the policy direction either DIRECTION_IN or DIRECTION_OUT 377c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * @param transform a transport mode {@code IpSecTransform} 378c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * @throws IOException indicating that the transform could not be applied 379b64993559b049327365bb63e81e8046a892a1033Nathan Harold */ 380a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold public void applyTransportModeTransform( 381a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold FileDescriptor socket, int direction, IpSecTransform transform) 382b64993559b049327365bb63e81e8046a892a1033Nathan Harold throws IOException { 3838dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold // We dup() the FileDescriptor here because if we don't, then the ParcelFileDescriptor() 384b548d251b7995a5b76e495978b61ad6c3c4183d1Nathan Harold // constructor takes control and closes the user's FD when we exit the method. 3858dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold try (ParcelFileDescriptor pfd = ParcelFileDescriptor.dup(socket)) { 386a25233123b2d29fde83dd686f6313f0a232c5b2aNathan Harold mService.applyTransportModeTransform(pfd, direction, transform.getResourceId()); 3878dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } catch (RemoteException e) { 3888dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold throw e.rethrowFromSystemServer(); 3898dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 390b64993559b049327365bb63e81e8046a892a1033Nathan Harold } 391b64993559b049327365bb63e81e8046a892a1033Nathan Harold 392b64993559b049327365bb63e81e8046a892a1033Nathan Harold /** 393330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Apply an active Tunnel Mode IPsec Transform to a network, which will tunnel all traffic to 394330e1089da80cddcd68758512370d217b19f8890Nathan Harold * and from that network's interface with IPsec (applies an outer IP header and IPsec Header to 395330e1089da80cddcd68758512370d217b19f8890Nathan Harold * all traffic, and expects an additional IP header and IPsec Header on all inbound traffic). 396330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Applications should probably not use this API directly. Instead, they should use {@link 397330e1089da80cddcd68758512370d217b19f8890Nathan Harold * VpnService} to provide VPN capability in a more generic fashion. 398330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 3995fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * <p>TODO: Update javadoc for tunnel mode APIs at the same time the APIs are re-worked. 4005fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * 401330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param net a {@link Network} that will be tunneled via IP Sec. 402330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param transform an {@link IpSecTransform}, which must be an active Tunnel Mode transform. 403330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @hide 404330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 405330e1089da80cddcd68758512370d217b19f8890Nathan Harold public void applyTunnelModeTransform(Network net, IpSecTransform transform) {} 406330e1089da80cddcd68758512370d217b19f8890Nathan Harold 407330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 408c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * Remove an IPsec transform from a stream socket. 409c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * 410f73d252c8f51936eec49313f4cc26f1da7727b6cNathan Harold * <p>Once removed, traffic on the socket will not be encrypted. Removing transforms from a 411f73d252c8f51936eec49313f4cc26f1da7727b6cNathan Harold * socket allows the socket to be reused for communication in the clear. 412c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * 413c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * <p>If an {@code IpSecTransform} object applied to this socket was deallocated by calling 414c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * {@link IpSecTransform#close()}, then communication on the socket will fail until this method 415c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * is called. 416330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 417c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * @param socket a socket that previously had a transform applied to it 418c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * @throws IOException indicating that the transform could not be removed from the socket 419330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 420f73d252c8f51936eec49313f4cc26f1da7727b6cNathan Harold public void removeTransportModeTransforms(Socket socket) 4210bfb2075320a9f648fc2b3fcdfc58f425c9a685aNathan Harold throws IOException { 422f73d252c8f51936eec49313f4cc26f1da7727b6cNathan Harold removeTransportModeTransforms(socket.getFileDescriptor$()); 423330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 424330e1089da80cddcd68758512370d217b19f8890Nathan Harold 425330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 426c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * Remove an IPsec transform from a datagram socket. 427330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 428f73d252c8f51936eec49313f4cc26f1da7727b6cNathan Harold * <p>Once removed, traffic on the socket will not be encrypted. Removing transforms from a 429f73d252c8f51936eec49313f4cc26f1da7727b6cNathan Harold * socket allows the socket to be reused for communication in the clear. 430c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * 431c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * <p>If an {@code IpSecTransform} object applied to this socket was deallocated by calling 432c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * {@link IpSecTransform#close()}, then communication on the socket will fail until this method 433c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * is called. 434c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * 435c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * @param socket a socket that previously had a transform applied to it 436c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * @throws IOException indicating that the transform could not be removed from the socket 437330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 438f73d252c8f51936eec49313f4cc26f1da7727b6cNathan Harold public void removeTransportModeTransforms(DatagramSocket socket) 4390bfb2075320a9f648fc2b3fcdfc58f425c9a685aNathan Harold throws IOException { 440f73d252c8f51936eec49313f4cc26f1da7727b6cNathan Harold removeTransportModeTransforms(socket.getFileDescriptor$()); 441330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 442330e1089da80cddcd68758512370d217b19f8890Nathan Harold 443b64993559b049327365bb63e81e8046a892a1033Nathan Harold /** 444c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * Remove an IPsec transform from a socket. 445c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * 446f73d252c8f51936eec49313f4cc26f1da7727b6cNathan Harold * <p>Once removed, traffic on the socket will not be encrypted. Removing transforms from a 447f73d252c8f51936eec49313f4cc26f1da7727b6cNathan Harold * socket allows the socket to be reused for communication in the clear. 448b64993559b049327365bb63e81e8046a892a1033Nathan Harold * 449c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * <p>If an {@code IpSecTransform} object applied to this socket was deallocated by calling 450c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * {@link IpSecTransform#close()}, then communication on the socket will fail until this method 451c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * is called. 452c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * 453c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * @param socket a socket that previously had a transform applied to it 454c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * @throws IOException indicating that the transform could not be removed from the socket 455b64993559b049327365bb63e81e8046a892a1033Nathan Harold */ 456f73d252c8f51936eec49313f4cc26f1da7727b6cNathan Harold public void removeTransportModeTransforms(FileDescriptor socket) 4570bfb2075320a9f648fc2b3fcdfc58f425c9a685aNathan Harold throws IOException { 4588dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold try (ParcelFileDescriptor pfd = ParcelFileDescriptor.dup(socket)) { 459f73d252c8f51936eec49313f4cc26f1da7727b6cNathan Harold mService.removeTransportModeTransforms(pfd); 46093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } catch (RemoteException e) { 46193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold throw e.rethrowFromSystemServer(); 46293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 46393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 464330e1089da80cddcd68758512370d217b19f8890Nathan Harold 465330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 466330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Remove a Tunnel Mode IPsec Transform from a {@link Network}. This must be used as part of 467330e1089da80cddcd68758512370d217b19f8890Nathan Harold * cleanup if a tunneled Network experiences a change in default route. The Network will drop 468330e1089da80cddcd68758512370d217b19f8890Nathan Harold * all traffic that cannot be routed to the Tunnel's outbound interface. If that interface is 469330e1089da80cddcd68758512370d217b19f8890Nathan Harold * lost, all traffic will drop. 470330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 4715fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * <p>TODO: Update javadoc for tunnel mode APIs at the same time the APIs are re-worked. 4725fb929032de14ca78163e1d0c42c34f6fb287da4Jonathan Basseri * 473330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param net a network that currently has transform applied to it. 474330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param transform a Tunnel Mode IPsec Transform that has been previously applied to the given 475330e1089da80cddcd68758512370d217b19f8890Nathan Harold * network 476330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @hide 477330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 478330e1089da80cddcd68758512370d217b19f8890Nathan Harold public void removeTunnelModeTransform(Network net, IpSecTransform transform) {} 479330e1089da80cddcd68758512370d217b19f8890Nathan Harold 480330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 481c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * This class provides access to a UDP encapsulation Socket. 482330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 483c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * <p>{@code UdpEncapsulationSocket} wraps a system-provided datagram socket intended for IKEv2 484c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * signalling and UDP encapsulated IPsec traffic. Instances can be obtained by calling {@link 485c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * IpSecManager#openUdpEncapsulationSocket}. The provided socket cannot be re-bound by the 486c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * caller. The caller should not close the {@code FileDescriptor} returned by {@link 487c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * #getSocket}, but should use {@link #close} instead. 488c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * 489c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * <p>Allowing the user to close or unbind a UDP encapsulation socket could impact the traffic 490c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * of the next user who binds to that port. To prevent this scenario, these sockets are held 491c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * open by the system so that they may only be closed by calling {@link #close} or when the user 492c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * process exits. 493330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 494330e1089da80cddcd68758512370d217b19f8890Nathan Harold public static final class UdpEncapsulationSocket implements AutoCloseable { 4958dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold private final ParcelFileDescriptor mPfd; 4961afbef40c68373f3871eed087c546cfe1911ee36Nathan Harold private final IIpSecService mService; 4976119d8d1d0d89b0d4c4ac822e9e93bb47f1ebd9aNathan Harold private int mResourceId = INVALID_RESOURCE_ID; 4988dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold private final int mPort; 499330e1089da80cddcd68758512370d217b19f8890Nathan Harold private final CloseGuard mCloseGuard = CloseGuard.get(); 500330e1089da80cddcd68758512370d217b19f8890Nathan Harold 50193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold private UdpEncapsulationSocket(@NonNull IIpSecService service, int port) 5028dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold throws ResourceUnavailableException, IOException { 5031afbef40c68373f3871eed087c546cfe1911ee36Nathan Harold mService = service; 5048dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold try { 5058dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold IpSecUdpEncapResponse result = 5068dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold mService.openUdpEncapsulationSocket(port, new Binder()); 5078dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold switch (result.status) { 5088dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold case Status.OK: 5098dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold break; 5108dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold case Status.RESOURCE_UNAVAILABLE: 5118dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold throw new ResourceUnavailableException( 5128dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold "No more Sockets may be allocated by this requester."); 5138dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold default: 5148dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold throw new RuntimeException( 5158dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold "Unknown status returned by IpSecService: " + result.status); 5168dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 5178dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold mResourceId = result.resourceId; 5188dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold mPort = result.port; 5198dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold mPfd = result.fileDescriptor; 5208dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } catch (RemoteException e) { 5218dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold throw e.rethrowFromSystemServer(); 5228dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 523330e1089da80cddcd68758512370d217b19f8890Nathan Harold mCloseGuard.open("constructor"); 524330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 525330e1089da80cddcd68758512370d217b19f8890Nathan Harold 526c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri /** Get the wrapped socket. */ 527330e1089da80cddcd68758512370d217b19f8890Nathan Harold public FileDescriptor getSocket() { 5288dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold if (mPfd == null) { 5298dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold return null; 5308dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 5318dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold return mPfd.getFileDescriptor(); 532330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 533330e1089da80cddcd68758512370d217b19f8890Nathan Harold 534c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri /** Get the bound port of the wrapped socket. */ 535330e1089da80cddcd68758512370d217b19f8890Nathan Harold public int getPort() { 5368dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold return mPort; 537330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 538330e1089da80cddcd68758512370d217b19f8890Nathan Harold 539330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 540c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * Close this socket. 541330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 542c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * <p>This closes the wrapped socket. Open encapsulation sockets count against a user's 543c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * resource limits, and forgetting to close them eventually will result in {@link 544c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * ResourceUnavailableException} being thrown. 545330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 546c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri @Override 5470bfb2075320a9f648fc2b3fcdfc58f425c9a685aNathan Harold public void close() throws IOException { 5488dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold try { 5498dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold mService.closeUdpEncapsulationSocket(mResourceId); 5506119d8d1d0d89b0d4c4ac822e9e93bb47f1ebd9aNathan Harold mResourceId = INVALID_RESOURCE_ID; 5518dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } catch (RemoteException e) { 5528dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold throw e.rethrowFromSystemServer(); 5538dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 5548dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold 5558dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold try { 5568dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold mPfd.close(); 5578dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } catch (IOException e) { 5588dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold Log.e(TAG, "Failed to close UDP Encapsulation Socket with Port= " + mPort); 5598dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold throw e; 5608dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 561330e1089da80cddcd68758512370d217b19f8890Nathan Harold mCloseGuard.close(); 562330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 563330e1089da80cddcd68758512370d217b19f8890Nathan Harold 564c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri /** Check that the socket was closed properly. */ 565330e1089da80cddcd68758512370d217b19f8890Nathan Harold @Override 566330e1089da80cddcd68758512370d217b19f8890Nathan Harold protected void finalize() throws Throwable { 567330e1089da80cddcd68758512370d217b19f8890Nathan Harold if (mCloseGuard != null) { 568330e1089da80cddcd68758512370d217b19f8890Nathan Harold mCloseGuard.warnIfOpen(); 569330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 570330e1089da80cddcd68758512370d217b19f8890Nathan Harold close(); 571330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 5728dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold 5738dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold /** @hide */ 574a10003d5de52339f4d30fedd7294941378e5f13cNathan Harold @VisibleForTesting 575a10003d5de52339f4d30fedd7294941378e5f13cNathan Harold public int getResourceId() { 5768dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold return mResourceId; 5778dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 578330e1089da80cddcd68758512370d217b19f8890Nathan Harold }; 579330e1089da80cddcd68758512370d217b19f8890Nathan Harold 580330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 581c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * Open a socket for UDP encapsulation and bind to the given port. 582330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 583c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * <p>See {@link UdpEncapsulationSocket} for the proper way to close the returned socket. 584330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 585c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * @param port a local UDP port 586c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * @return a socket that is bound to the given port 587c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * @throws IOException indicating that the socket could not be opened or bound 588c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * @throws ResourceUnavailableException indicating that too many encapsulation sockets are open 589330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 590330e1089da80cddcd68758512370d217b19f8890Nathan Harold // Returning a socket in this fashion that has been created and bound by the system 591330e1089da80cddcd68758512370d217b19f8890Nathan Harold // is the only safe way to ensure that a socket is both accessible to the user and 592330e1089da80cddcd68758512370d217b19f8890Nathan Harold // safely usable for Encapsulation without allowing a user to possibly unbind from/close 593330e1089da80cddcd68758512370d217b19f8890Nathan Harold // the port, which could potentially impact the traffic of the next user who binds to that 594330e1089da80cddcd68758512370d217b19f8890Nathan Harold // socket. 595330e1089da80cddcd68758512370d217b19f8890Nathan Harold public UdpEncapsulationSocket openUdpEncapsulationSocket(int port) 596330e1089da80cddcd68758512370d217b19f8890Nathan Harold throws IOException, ResourceUnavailableException { 5978dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold /* 5988dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold * Most range checking is done in the service, but this version of the constructor expects 5998dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold * a valid port number, and zero cannot be checked after being passed to the service. 6008dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold */ 6018dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold if (port == 0) { 6028dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold throw new IllegalArgumentException("Specified port must be a valid port number!"); 6038dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 6041afbef40c68373f3871eed087c546cfe1911ee36Nathan Harold return new UdpEncapsulationSocket(mService, port); 605330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 606330e1089da80cddcd68758512370d217b19f8890Nathan Harold 607330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 608c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * Open a socket for UDP encapsulation. 609330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 610c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * <p>See {@link UdpEncapsulationSocket} for the proper way to close the returned socket. 611330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 612c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * <p>The local port of the returned socket can be obtained by calling {@link 613c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * UdpEncapsulationSocket#getPort()}. 614330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 615c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * @return a socket that is bound to a local port 616c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * @throws IOException indicating that the socket could not be opened or bound 617c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * @throws ResourceUnavailableException indicating that too many encapsulation sockets are open 618330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 619330e1089da80cddcd68758512370d217b19f8890Nathan Harold // Returning a socket in this fashion that has been created and bound by the system 620330e1089da80cddcd68758512370d217b19f8890Nathan Harold // is the only safe way to ensure that a socket is both accessible to the user and 621330e1089da80cddcd68758512370d217b19f8890Nathan Harold // safely usable for Encapsulation without allowing a user to possibly unbind from/close 622330e1089da80cddcd68758512370d217b19f8890Nathan Harold // the port, which could potentially impact the traffic of the next user who binds to that 623330e1089da80cddcd68758512370d217b19f8890Nathan Harold // socket. 624330e1089da80cddcd68758512370d217b19f8890Nathan Harold public UdpEncapsulationSocket openUdpEncapsulationSocket() 625330e1089da80cddcd68758512370d217b19f8890Nathan Harold throws IOException, ResourceUnavailableException { 6268dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold return new UdpEncapsulationSocket(mService, 0); 627330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 628330e1089da80cddcd68758512370d217b19f8890Nathan Harold 629330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 630c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * This class represents an IpSecTunnelInterface 631c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * 632c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * <p>IpSecTunnelInterface objects track tunnel interfaces that serve as 633c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * local endpoints for IPsec tunnels. 634c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * 635c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * <p>Creating an IpSecTunnelInterface creates a device to which IpSecTransforms may be 636c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * applied to provide IPsec security to packets sent through the tunnel. While a tunnel 637c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * cannot be used in standalone mode within Android, the higher layers may use the tunnel 638c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * to create Network objects which are accessible to the Android system. 639c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * @hide 640c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold */ 641c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold @SystemApi 642c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold public static final class IpSecTunnelInterface implements AutoCloseable { 643c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold private final IIpSecService mService; 644c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold private final InetAddress mRemoteAddress; 645c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold private final InetAddress mLocalAddress; 646c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold private final Network mUnderlyingNetwork; 647c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold private final CloseGuard mCloseGuard = CloseGuard.get(); 648c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold private String mInterfaceName; 649c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold private int mResourceId = INVALID_RESOURCE_ID; 650c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold 651c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold /** Get the underlying SPI held by this object. */ 652c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold public String getInterfaceName() { 653c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold return mInterfaceName; 654c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold } 655c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold 656c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold /** 657c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * Add an address to the IpSecTunnelInterface 658c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * 659c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * <p>Add an address which may be used as the local inner address for 660c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * tunneled traffic. 661c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * 662c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * @param address the local address for traffic inside the tunnel 663c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * @throws IOException if the address could not be added 664c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * @hide 665c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold */ 666c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold public void addAddress(LinkAddress address) throws IOException { 667c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold } 668c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold 669c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold /** 670c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * Remove an address from the IpSecTunnelInterface 671c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * 672c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * <p>Remove an address which was previously added to the IpSecTunnelInterface 673c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * 674c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * @param address to be removed 675c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * @throws IOException if the address could not be removed 676c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * @hide 677c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold */ 678c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold public void removeAddress(LinkAddress address) throws IOException { 679c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold } 680c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold 681c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold private IpSecTunnelInterface(@NonNull IIpSecService service, 682c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold @NonNull InetAddress localAddress, @NonNull InetAddress remoteAddress, 683c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold @NonNull Network underlyingNetwork) 684c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold throws ResourceUnavailableException, IOException { 685c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold mService = service; 686c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold mLocalAddress = localAddress; 687c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold mRemoteAddress = remoteAddress; 688c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold mUnderlyingNetwork = underlyingNetwork; 6898149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong 6908149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong try { 6918149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong IpSecTunnelInterfaceResponse result = 6928149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong mService.createTunnelInterface( 6938149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong localAddress.getHostAddress(), 6948149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong remoteAddress.getHostAddress(), 6958149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong underlyingNetwork, 6968149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong new Binder()); 6978149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong switch (result.status) { 6988149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong case Status.OK: 6998149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong break; 7008149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong case Status.RESOURCE_UNAVAILABLE: 7018149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong throw new ResourceUnavailableException( 7028149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong "No more tunnel interfaces may be allocated by this requester."); 7038149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong default: 7048149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong throw new RuntimeException( 7058149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong "Unknown status returned by IpSecService: " + result.status); 7068149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong } 7078149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong mResourceId = result.resourceId; 7088149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong mInterfaceName = result.interfaceName; 7098149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong } catch (RemoteException e) { 7108149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong throw e.rethrowFromSystemServer(); 7118149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong } 7128149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong mCloseGuard.open("constructor"); 713c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold } 714c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold 715c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold /** 716c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * Delete an IpSecTunnelInterface 717c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * 718c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * <p>Calling close will deallocate the IpSecTunnelInterface and all of its system 719c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * resources. Any packets bound for this interface either inbound or outbound will 720c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * all be lost. 721c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold */ 722c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold @Override 723c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold public void close() { 7248149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong try { 7258149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong mService.deleteTunnelInterface(mResourceId); 7268149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong mResourceId = INVALID_RESOURCE_ID; 7278149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong } catch (RemoteException e) { 7288149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong throw e.rethrowFromSystemServer(); 7298149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong } 730c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold mCloseGuard.close(); 731c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold } 732c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold 733c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold /** Check that the Interface was closed properly. */ 734c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold @Override 735c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold protected void finalize() throws Throwable { 736c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold if (mCloseGuard != null) { 737c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold mCloseGuard.warnIfOpen(); 738c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold } 739c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold close(); 740c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold } 7418149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong 7428149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong /** @hide */ 7438149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong @VisibleForTesting 7448149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong public int getResourceId() { 7458149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong return mResourceId; 7468149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong } 747c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold } 748c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold 749c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold /** 750c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * Create a new IpSecTunnelInterface as a local endpoint for tunneled IPsec traffic. 751c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * 7528149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong * <p>An application that creates tunnels is responsible for cleaning up the tunnel when the 7538149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong * underlying network goes away, and the onLost() callback is received. 7548149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong * 755c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * @param localAddress The local addres of the tunnel 756c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * @param remoteAddress The local addres of the tunnel 757c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * @param underlyingNetwork the {@link Network} that will carry traffic for this tunnel. 758c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * This network should almost certainly be a network such as WiFi with an L2 address. 759c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * @return a new {@link IpSecManager#IpSecTunnelInterface} with the specified properties 760c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * @throws IOException indicating that the socket could not be opened or bound 761c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * @throws ResourceUnavailableException indicating that too many encapsulation sockets are open 762c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * @hide 763c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold */ 764c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold @SystemApi 7655a920ca377efaaaaabf3fe6c77111d8158202055Nathan Harold @RequiresPermission(android.Manifest.permission.NETWORK_STACK) 766c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold public IpSecTunnelInterface createIpSecTunnelInterface(@NonNull InetAddress localAddress, 767c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold @NonNull InetAddress remoteAddress, @NonNull Network underlyingNetwork) 768c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold throws ResourceUnavailableException, IOException { 769c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold return new IpSecTunnelInterface(mService, localAddress, remoteAddress, underlyingNetwork); 770c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold } 771c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold 772c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold /** 773c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * Apply a transform to the IpSecTunnelInterface 774c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * 775c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * @param tunnel The {@link IpSecManager#IpSecTunnelInterface} that will use the supplied 776c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * transform. 777c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * @param direction the direction, {@link DIRECTION_OUT} or {@link #DIRECTION_IN} in which 778c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * the transform will be used. 779c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * @param transform an {@link IpSecTransform} created in tunnel mode 780c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * @throws IOException indicating that the transform could not be applied due to a lower 781c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * layer failure. 782c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold * @hide 783c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold */ 784c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold @SystemApi 7855a920ca377efaaaaabf3fe6c77111d8158202055Nathan Harold @RequiresPermission(android.Manifest.permission.NETWORK_STACK) 786e0d448f31eb9f7e63d13ef45b04853d95c00670aBenedict Wong public void applyTunnelModeTransform(IpSecTunnelInterface tunnel, int direction, 787c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold IpSecTransform transform) throws IOException { 7888149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong try { 7898149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong mService.applyTunnelModeTransform( 7908149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong tunnel.getResourceId(), direction, transform.getResourceId()); 7918149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong } catch (RemoteException e) { 7928149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong throw e.rethrowFromSystemServer(); 7938149f6eb6c0280078dc41d72027d1241e875ea02Benedict Wong } 794c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold } 795c47eaccf7c09541c6dd3d3ebedcb2e224346d903Nathan Harold /** 796c61b70d12d23da97013ee5e44f101609215d1bffJonathan Basseri * Construct an instance of IpSecManager within an application context. 797330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 798330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param context the application context for this manager 799330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @hide 800330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 8011afbef40c68373f3871eed087c546cfe1911ee36Nathan Harold public IpSecManager(IIpSecService service) { 802330e1089da80cddcd68758512370d217b19f8890Nathan Harold mService = checkNotNull(service, "missing service"); 803330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 804330e1089da80cddcd68758512370d217b19f8890Nathan Harold} 805