IpSecManager.java revision 330e1089da80cddcd68758512370d217b19f8890
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
20330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport android.annotation.SystemApi;
21330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport android.content.Context;
22330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport android.os.INetworkManagementService;
23330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport android.os.ParcelFileDescriptor;
24330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport android.util.AndroidException;
25330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport dalvik.system.CloseGuard;
26330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.io.FileDescriptor;
27330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.io.IOException;
28330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.net.DatagramSocket;
29330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.net.InetAddress;
30330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.net.Socket;
31330e1089da80cddcd68758512370d217b19f8890Nathan Harold
32330e1089da80cddcd68758512370d217b19f8890Nathan Harold/**
33330e1089da80cddcd68758512370d217b19f8890Nathan Harold * This class contains methods for managing IPsec sessions, which will perform kernel-space
34330e1089da80cddcd68758512370d217b19f8890Nathan Harold * encryption and decryption of socket or Network traffic.
35330e1089da80cddcd68758512370d217b19f8890Nathan Harold *
36330e1089da80cddcd68758512370d217b19f8890Nathan Harold * <p>An IpSecManager may be obtained by calling {@link
37330e1089da80cddcd68758512370d217b19f8890Nathan Harold * android.content.Context#getSystemService(String) Context#getSystemService(String)} with {@link
38330e1089da80cddcd68758512370d217b19f8890Nathan Harold * android.content.Context#IPSEC_SERVICE Context#IPSEC_SERVICE}
39330e1089da80cddcd68758512370d217b19f8890Nathan Harold */
40330e1089da80cddcd68758512370d217b19f8890Nathan Haroldpublic final class IpSecManager {
41330e1089da80cddcd68758512370d217b19f8890Nathan Harold    private static final String TAG = "IpSecManager";
42330e1089da80cddcd68758512370d217b19f8890Nathan Harold
43330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
44330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Indicates that the combination of remote InetAddress and SPI was non-unique for a given
45330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * request. If encountered, selection of a new SPI is required before a transform may be
46330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * created. Note, this should happen very rarely if the SPI is chosen to be sufficiently random
47330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * or reserved using reserveSecurityParameterIndex.
48330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
49330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public static final class SpiUnavailableException extends AndroidException {
50330e1089da80cddcd68758512370d217b19f8890Nathan Harold        private final int mSpi;
51330e1089da80cddcd68758512370d217b19f8890Nathan Harold
52330e1089da80cddcd68758512370d217b19f8890Nathan Harold        /**
53330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * Construct an exception indicating that a transform with the given SPI is already in use
54330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * or otherwise unavailable.
55330e1089da80cddcd68758512370d217b19f8890Nathan Harold         *
56330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * @param msg Description indicating the colliding SPI
57330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * @param spi the SPI that could not be used due to a collision
58330e1089da80cddcd68758512370d217b19f8890Nathan Harold         */
59330e1089da80cddcd68758512370d217b19f8890Nathan Harold        SpiUnavailableException(String msg, int spi) {
60330e1089da80cddcd68758512370d217b19f8890Nathan Harold            super(msg + "(spi: " + spi + ")");
61330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mSpi = spi;
62330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
63330e1089da80cddcd68758512370d217b19f8890Nathan Harold
64330e1089da80cddcd68758512370d217b19f8890Nathan Harold        /** Retrieve the SPI that caused a collision */
65330e1089da80cddcd68758512370d217b19f8890Nathan Harold        public int getSpi() {
66330e1089da80cddcd68758512370d217b19f8890Nathan Harold            return mSpi;
67330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
68330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
69330e1089da80cddcd68758512370d217b19f8890Nathan Harold
70330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
71330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Indicates that the requested system resource for IPsec, such as a socket or other system
72330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * resource is unavailable. If this exception is thrown, try releasing allocated objects of the
73330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * type requested.
74330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
75330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public static final class ResourceUnavailableException extends AndroidException {
76330e1089da80cddcd68758512370d217b19f8890Nathan Harold
77330e1089da80cddcd68758512370d217b19f8890Nathan Harold        ResourceUnavailableException(String msg) {
78330e1089da80cddcd68758512370d217b19f8890Nathan Harold            super(msg);
79330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
80330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
81330e1089da80cddcd68758512370d217b19f8890Nathan Harold
82330e1089da80cddcd68758512370d217b19f8890Nathan Harold    private final Context mContext;
83330e1089da80cddcd68758512370d217b19f8890Nathan Harold    private final INetworkManagementService mService;
84330e1089da80cddcd68758512370d217b19f8890Nathan Harold
85330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public static final class SecurityParameterIndex implements AutoCloseable {
86330e1089da80cddcd68758512370d217b19f8890Nathan Harold        private final Context mContext;
87330e1089da80cddcd68758512370d217b19f8890Nathan Harold        private final InetAddress mDestinationAddress;
88330e1089da80cddcd68758512370d217b19f8890Nathan Harold        private final CloseGuard mCloseGuard = CloseGuard.get();
89330e1089da80cddcd68758512370d217b19f8890Nathan Harold        private int mSpi;
90330e1089da80cddcd68758512370d217b19f8890Nathan Harold
91330e1089da80cddcd68758512370d217b19f8890Nathan Harold        /** Return the underlying SPI held by this object */
92330e1089da80cddcd68758512370d217b19f8890Nathan Harold        public int getSpi() {
93330e1089da80cddcd68758512370d217b19f8890Nathan Harold            return mSpi;
94330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
95330e1089da80cddcd68758512370d217b19f8890Nathan Harold
96330e1089da80cddcd68758512370d217b19f8890Nathan Harold        private SecurityParameterIndex(Context context, InetAddress destinationAddress, int spi)
97330e1089da80cddcd68758512370d217b19f8890Nathan Harold                throws ResourceUnavailableException, SpiUnavailableException {
98330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mContext = context;
99330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mDestinationAddress = destinationAddress;
100330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mSpi = spi;
101330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mCloseGuard.open("open");
102330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
103330e1089da80cddcd68758512370d217b19f8890Nathan Harold
104330e1089da80cddcd68758512370d217b19f8890Nathan Harold        /**
105330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * Release an SPI that was previously reserved.
106330e1089da80cddcd68758512370d217b19f8890Nathan Harold         *
107330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * <p>Release an SPI for use by other users in the system. This will fail if the SPI is
108330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * currently in use by an IpSecTransform.
109330e1089da80cddcd68758512370d217b19f8890Nathan Harold         *
110330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * @param destinationAddress SPIs must be unique for each combination of SPI and destination
111330e1089da80cddcd68758512370d217b19f8890Nathan Harold         *     address. Thus, the destinationAddress to which the SPI will communicate must be
112330e1089da80cddcd68758512370d217b19f8890Nathan Harold         *     supplied.
113330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * @param spi the previously reserved SPI to be freed.
114330e1089da80cddcd68758512370d217b19f8890Nathan Harold         */
115330e1089da80cddcd68758512370d217b19f8890Nathan Harold        @Override
116330e1089da80cddcd68758512370d217b19f8890Nathan Harold        public void close() {
117330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mSpi = INVALID_SECURITY_PARAMETER_INDEX; // TODO: Invalid SPI
118330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mCloseGuard.close();
119330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
120330e1089da80cddcd68758512370d217b19f8890Nathan Harold
121330e1089da80cddcd68758512370d217b19f8890Nathan Harold        @Override
122330e1089da80cddcd68758512370d217b19f8890Nathan Harold        protected void finalize() {
123330e1089da80cddcd68758512370d217b19f8890Nathan Harold            if (mCloseGuard != null) {
124330e1089da80cddcd68758512370d217b19f8890Nathan Harold                mCloseGuard.warnIfOpen();
125330e1089da80cddcd68758512370d217b19f8890Nathan Harold            }
126330e1089da80cddcd68758512370d217b19f8890Nathan Harold
127330e1089da80cddcd68758512370d217b19f8890Nathan Harold            close();
128330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
129330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
130330e1089da80cddcd68758512370d217b19f8890Nathan Harold
131330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
132330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * The Security Parameter Index, SPI, 0 indicates an unknown or invalid index.
133330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
134330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * <p>No IPsec packet may contain an SPI of 0.
135330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
136330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public static final int INVALID_SECURITY_PARAMETER_INDEX = 0;
137330e1089da80cddcd68758512370d217b19f8890Nathan Harold
138330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
139330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Reserve an SPI for traffic bound towards the specified destination address.
140330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
141330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * <p>If successful, this SPI is guaranteed available until released by a call to {@link
142330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * SecurityParameterIndex#close()}.
143330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
144330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param destinationAddress SPIs must be unique for each combination of SPI and destination
145330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *     address.
146330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param requestedSpi the requested SPI, or '0' to allocate a random SPI.
147330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @return the reserved SecurityParameterIndex
148330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @throws ResourceUnavailableException indicating that too many SPIs are currently allocated
149330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *     for this user
150330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @throws SpiUnavailableException indicating that a particular SPI cannot be reserved
151330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
152330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public SecurityParameterIndex reserveSecurityParameterIndex(
153330e1089da80cddcd68758512370d217b19f8890Nathan Harold            InetAddress destinationAddress, int requestedSpi)
154330e1089da80cddcd68758512370d217b19f8890Nathan Harold            throws SpiUnavailableException, ResourceUnavailableException {
155330e1089da80cddcd68758512370d217b19f8890Nathan Harold        return new SecurityParameterIndex(mContext, destinationAddress, requestedSpi);
156330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
157330e1089da80cddcd68758512370d217b19f8890Nathan Harold
158330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
159330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Apply an active Transport Mode IPsec Transform to a stream socket to perform IPsec
160330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * encapsulation of the traffic flowing between the socket and the remote InetAddress of that
161330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * transform. For security reasons, attempts to send traffic to any IP address other than the
162330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * address associated with that transform will throw an IOException. In addition, if the
163330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * IpSecTransform is later deactivated, the socket will throw an IOException on any calls to
164330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * send() or receive() until the transform is removed from the socket by calling {@link
165330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * #removeTransportModeTransform(Socket, IpSecTransform)};
166330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
167330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param socket a stream socket
168330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param transform an {@link IpSecTransform}, which must be an active Transport Mode transform.
169330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
170330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public void applyTransportModeTransform(Socket socket, IpSecTransform transform)
171330e1089da80cddcd68758512370d217b19f8890Nathan Harold            throws IOException {
172330e1089da80cddcd68758512370d217b19f8890Nathan Harold        applyTransportModeTransform(ParcelFileDescriptor.fromSocket(socket), transform);
173330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
174330e1089da80cddcd68758512370d217b19f8890Nathan Harold
175330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
176330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Apply an active Transport Mode IPsec Transform to a datagram socket to perform IPsec
177330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * encapsulation of the traffic flowing between the socket and the remote InetAddress of that
178330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * transform. For security reasons, attempts to send traffic to any IP address other than the
179330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * address associated with that transform will throw an IOException. In addition, if the
180330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * IpSecTransform is later deactivated, the socket will throw an IOException on any calls to
181330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * send() or receive() until the transform is removed from the socket by calling {@link
182330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * #removeTransportModeTransform(DatagramSocket, IpSecTransform)};
183330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
184330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param socket a datagram socket
185330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param transform an {@link IpSecTransform}, which must be an active Transport Mode transform.
186330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
187330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public void applyTransportModeTransform(DatagramSocket socket, IpSecTransform transform)
188330e1089da80cddcd68758512370d217b19f8890Nathan Harold            throws IOException {
189330e1089da80cddcd68758512370d217b19f8890Nathan Harold        applyTransportModeTransform(ParcelFileDescriptor.fromDatagramSocket(socket), transform);
190330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
191330e1089da80cddcd68758512370d217b19f8890Nathan Harold
192330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /* Call down to activate a transform */
193330e1089da80cddcd68758512370d217b19f8890Nathan Harold    private void applyTransportModeTransform(ParcelFileDescriptor pfd, IpSecTransform transform) {}
194330e1089da80cddcd68758512370d217b19f8890Nathan Harold
195330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
196330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Apply an active Tunnel Mode IPsec Transform to a network, which will tunnel all traffic to
197330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * and from that network's interface with IPsec (applies an outer IP header and IPsec Header to
198330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * all traffic, and expects an additional IP header and IPsec Header on all inbound traffic).
199330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Applications should probably not use this API directly. Instead, they should use {@link
200330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * VpnService} to provide VPN capability in a more generic fashion.
201330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
202330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param net a {@link Network} that will be tunneled via IP Sec.
203330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param transform an {@link IpSecTransform}, which must be an active Tunnel Mode transform.
204330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @hide
205330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
206330e1089da80cddcd68758512370d217b19f8890Nathan Harold    @SystemApi
207330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public void applyTunnelModeTransform(Network net, IpSecTransform transform) {}
208330e1089da80cddcd68758512370d217b19f8890Nathan Harold
209330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
210330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Remove a transform from a given stream socket. Once removed, traffic on the socket will not
211330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * be encypted. This allows sockets that have been used for IPsec to be reclaimed for
212330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * communication in the clear in the event socket reuse is desired. This operation will succeed
213330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * regardless of the underlying state of a transform. If a transform is removed, communication
214330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * on all sockets to which that transform was applied will fail until this method is called.
215330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
216330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param socket a socket that previously had a transform applied to it.
217330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param transform the IPsec Transform that was previously applied to the given socket
218330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
219330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public void removeTransportModeTransform(Socket socket, IpSecTransform transform) {
220330e1089da80cddcd68758512370d217b19f8890Nathan Harold        removeTransportModeTransform(ParcelFileDescriptor.fromSocket(socket), transform);
221330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
222330e1089da80cddcd68758512370d217b19f8890Nathan Harold
223330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
224330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Remove a transform from a given datagram socket. Once removed, traffic on the socket will not
225330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * be encypted. This allows sockets that have been used for IPsec to be reclaimed for
226330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * communication in the clear in the event socket reuse is desired. This operation will succeed
227330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * regardless of the underlying state of a transform. If a transform is removed, communication
228330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * on all sockets to which that transform was applied will fail until this method is called.
229330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
230330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param socket a socket that previously had a transform applied to it.
231330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param transform the IPsec Transform that was previously applied to the given socket
232330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
233330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public void removeTransportModeTransform(DatagramSocket socket, IpSecTransform transform) {
234330e1089da80cddcd68758512370d217b19f8890Nathan Harold        removeTransportModeTransform(ParcelFileDescriptor.fromDatagramSocket(socket), transform);
235330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
236330e1089da80cddcd68758512370d217b19f8890Nathan Harold
237330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /* Call down to activate a transform */
238330e1089da80cddcd68758512370d217b19f8890Nathan Harold    private void removeTransportModeTransform(ParcelFileDescriptor pfd, IpSecTransform transform) {}
239330e1089da80cddcd68758512370d217b19f8890Nathan Harold
240330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
241330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Remove a Tunnel Mode IPsec Transform from a {@link Network}. This must be used as part of
242330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * cleanup if a tunneled Network experiences a change in default route. The Network will drop
243330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * all traffic that cannot be routed to the Tunnel's outbound interface. If that interface is
244330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * lost, all traffic will drop.
245330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
246330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param net a network that currently has transform applied to it.
247330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param transform a Tunnel Mode IPsec Transform that has been previously applied to the given
248330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *     network
249330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @hide
250330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
251330e1089da80cddcd68758512370d217b19f8890Nathan Harold    @SystemApi
252330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public void removeTunnelModeTransform(Network net, IpSecTransform transform) {}
253330e1089da80cddcd68758512370d217b19f8890Nathan Harold
254330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
255330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Class providing access to a system-provided UDP Encapsulation Socket, which may be used for
256330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * IKE signalling as well as for inbound and outbound UDP encapsulated IPsec traffic.
257330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
258330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * <p>The socket provided by this class cannot be re-bound or closed via the inner
259330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * FileDescriptor. Instead, disposing of this socket requires a call to close().
260330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
261330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public static final class UdpEncapsulationSocket implements AutoCloseable {
262330e1089da80cddcd68758512370d217b19f8890Nathan Harold        private final FileDescriptor mFd;
263330e1089da80cddcd68758512370d217b19f8890Nathan Harold        private final Context mContext;
264330e1089da80cddcd68758512370d217b19f8890Nathan Harold        private final CloseGuard mCloseGuard = CloseGuard.get();
265330e1089da80cddcd68758512370d217b19f8890Nathan Harold
266330e1089da80cddcd68758512370d217b19f8890Nathan Harold        private UdpEncapsulationSocket(Context context, int port)
267330e1089da80cddcd68758512370d217b19f8890Nathan Harold                throws ResourceUnavailableException {
268330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mContext = context;
269330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mCloseGuard.open("constructor");
270330e1089da80cddcd68758512370d217b19f8890Nathan Harold            // TODO: go down to the kernel and get a socket on the specified
271330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mFd = new FileDescriptor();
272330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
273330e1089da80cddcd68758512370d217b19f8890Nathan Harold
274330e1089da80cddcd68758512370d217b19f8890Nathan Harold        private UdpEncapsulationSocket(Context context) throws ResourceUnavailableException {
275330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mContext = context;
276330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mCloseGuard.open("constructor");
277330e1089da80cddcd68758512370d217b19f8890Nathan Harold            // TODO: go get a random socket on a random port
278330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mFd = new FileDescriptor();
279330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
280330e1089da80cddcd68758512370d217b19f8890Nathan Harold
281330e1089da80cddcd68758512370d217b19f8890Nathan Harold        /** Access the inner UDP Encapsulation Socket */
282330e1089da80cddcd68758512370d217b19f8890Nathan Harold        public FileDescriptor getSocket() {
283330e1089da80cddcd68758512370d217b19f8890Nathan Harold            return mFd;
284330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
285330e1089da80cddcd68758512370d217b19f8890Nathan Harold
286330e1089da80cddcd68758512370d217b19f8890Nathan Harold        /** Retrieve the port number of the inner encapsulation socket */
287330e1089da80cddcd68758512370d217b19f8890Nathan Harold        public int getPort() {
288330e1089da80cddcd68758512370d217b19f8890Nathan Harold            return 0; // TODO get the port number from the Socket;
289330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
290330e1089da80cddcd68758512370d217b19f8890Nathan Harold
291330e1089da80cddcd68758512370d217b19f8890Nathan Harold        @Override
292330e1089da80cddcd68758512370d217b19f8890Nathan Harold        /**
293330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * Release the resources that have been reserved for this Socket.
294330e1089da80cddcd68758512370d217b19f8890Nathan Harold         *
295330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * <p>This method closes the underlying socket, reducing a user's allocated sockets in the
296330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * system. This must be done as part of cleanup following use of a socket. Failure to do so
297330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * will cause the socket to count against a total allocation limit for IpSec and eventually
298330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * fail due to resource limits.
299330e1089da80cddcd68758512370d217b19f8890Nathan Harold         *
300330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * @param fd a file descriptor previously returned as a UDP Encapsulation socket.
301330e1089da80cddcd68758512370d217b19f8890Nathan Harold         */
302330e1089da80cddcd68758512370d217b19f8890Nathan Harold        public void close() {
303330e1089da80cddcd68758512370d217b19f8890Nathan Harold            // TODO: Go close the socket
304330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mCloseGuard.close();
305330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
306330e1089da80cddcd68758512370d217b19f8890Nathan Harold
307330e1089da80cddcd68758512370d217b19f8890Nathan Harold        @Override
308330e1089da80cddcd68758512370d217b19f8890Nathan Harold        protected void finalize() throws Throwable {
309330e1089da80cddcd68758512370d217b19f8890Nathan Harold            if (mCloseGuard != null) {
310330e1089da80cddcd68758512370d217b19f8890Nathan Harold                mCloseGuard.warnIfOpen();
311330e1089da80cddcd68758512370d217b19f8890Nathan Harold            }
312330e1089da80cddcd68758512370d217b19f8890Nathan Harold
313330e1089da80cddcd68758512370d217b19f8890Nathan Harold            close();
314330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
315330e1089da80cddcd68758512370d217b19f8890Nathan Harold    };
316330e1089da80cddcd68758512370d217b19f8890Nathan Harold
317330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
318330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Open a socket that is bound to a free UDP port on the system.
319330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
320330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * <p>By binding in this manner and holding the FileDescriptor, the socket cannot be un-bound by
321330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * the caller. This provides safe access to a socket on a port that can later be used as a UDP
322330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Encapsulation port.
323330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
324330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * <p>This socket reservation works in conjunction with IpSecTransforms, which may re-use the
325330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * socket port. Explicitly opening this port is only necessary if communication is desired on
326330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * that port.
327330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
328330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param port a local UDP port to be reserved for UDP Encapsulation. is provided, then this
329330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *     method will bind to the specified port or fail. To retrieve the port number, call {@link
330330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *     android.system.Os#getsockname(FileDescriptor)}.
331330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @return a {@link UdpEncapsulationSocket} that is bound to the requested port for the lifetime
332330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *     of the object.
333330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
334330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // Returning a socket in this fashion that has been created and bound by the system
335330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // is the only safe way to ensure that a socket is both accessible to the user and
336330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // safely usable for Encapsulation without allowing a user to possibly unbind from/close
337330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // the port, which could potentially impact the traffic of the next user who binds to that
338330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // socket.
339330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public UdpEncapsulationSocket openUdpEncapsulationSocket(int port)
340330e1089da80cddcd68758512370d217b19f8890Nathan Harold            throws IOException, ResourceUnavailableException {
341330e1089da80cddcd68758512370d217b19f8890Nathan Harold        // Temporary code
342330e1089da80cddcd68758512370d217b19f8890Nathan Harold        return new UdpEncapsulationSocket(mContext, port);
343330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
344330e1089da80cddcd68758512370d217b19f8890Nathan Harold
345330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
346330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Open a socket that is bound to a port selected by the system.
347330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
348330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * <p>By binding in this manner and holding the FileDescriptor, the socket cannot be un-bound by
349330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * the caller. This provides safe access to a socket on a port that can later be used as a UDP
350330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Encapsulation port.
351330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
352330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * <p>This socket reservation works in conjunction with IpSecTransforms, which may re-use the
353330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * socket port. Explicitly opening this port is only necessary if communication is desired on
354330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * that port.
355330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
356330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @return a {@link UdpEncapsulationSocket} that is bound to an arbitrarily selected port
357330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
358330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // Returning a socket in this fashion that has been created and bound by the system
359330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // is the only safe way to ensure that a socket is both accessible to the user and
360330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // safely usable for Encapsulation without allowing a user to possibly unbind from/close
361330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // the port, which could potentially impact the traffic of the next user who binds to that
362330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // socket.
363330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public UdpEncapsulationSocket openUdpEncapsulationSocket()
364330e1089da80cddcd68758512370d217b19f8890Nathan Harold            throws IOException, ResourceUnavailableException {
365330e1089da80cddcd68758512370d217b19f8890Nathan Harold        // Temporary code
366330e1089da80cddcd68758512370d217b19f8890Nathan Harold        return new UdpEncapsulationSocket(mContext);
367330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
368330e1089da80cddcd68758512370d217b19f8890Nathan Harold
369330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
370330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Retrieve an instance of an IpSecManager within you application context
371330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
372330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param context the application context for this manager
373330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @hide
374330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
375330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public IpSecManager(Context context, INetworkManagementService service) {
376330e1089da80cddcd68758512370d217b19f8890Nathan Harold        mContext = checkNotNull(context, "missing context");
377330e1089da80cddcd68758512370d217b19f8890Nathan Harold        mService = checkNotNull(service, "missing service");
378330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
379330e1089da80cddcd68758512370d217b19f8890Nathan Harold}
380