1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package android.net;
17 
18 import android.os.Parcel;
19 import android.os.Parcelable;
20 import android.util.Log;
21 import java.net.InetAddress;
22 import java.net.UnknownHostException;
23 
24 /** @hide */
25 public final class IpSecConfig implements Parcelable {
26     private static final String TAG = "IpSecConfig";
27 
28     //MODE_TRANSPORT or MODE_TUNNEL
29     int mode;
30 
31     // For tunnel mode
32     InetAddress localAddress;
33 
34     InetAddress remoteAddress;
35 
36     // Limit selection by network interface
37     Network network;
38 
39     public static class Flow {
40         // Minimum requirements for identifying a transform
41         // SPI identifying the IPsec flow in packet processing
42         // and a remote IP address
43         int spi;
44 
45         // Encryption Algorithm
46         IpSecAlgorithm encryption;
47 
48         // Authentication Algorithm
49         IpSecAlgorithm authentication;
50     }
51 
52     Flow[] flow = new Flow[] {new Flow(), new Flow()};
53 
54     // For tunnel mode IPv4 UDP Encapsulation
55     // IpSecTransform#ENCAP_ESP_*, such as ENCAP_ESP_OVER_UDP_IKE
56     int encapType;
57     int encapLocalPort;
58     int encapRemotePort;
59 
60     // An interval, in seconds between the NattKeepalive packets
61     int nattKeepaliveInterval;
62 
63     // Transport or Tunnel
getMode()64     public int getMode() {
65         return mode;
66     }
67 
getLocalAddress()68     public InetAddress getLocalAddress() {
69         return localAddress;
70     }
71 
getSpi(int direction)72     public int getSpi(int direction) {
73         return flow[direction].spi;
74     }
75 
getRemoteAddress()76     public InetAddress getRemoteAddress() {
77         return remoteAddress;
78     }
79 
getEncryption(int direction)80     public IpSecAlgorithm getEncryption(int direction) {
81         return flow[direction].encryption;
82     }
83 
getAuthentication(int direction)84     public IpSecAlgorithm getAuthentication(int direction) {
85         return flow[direction].authentication;
86     }
87 
getNetwork()88     public Network getNetwork() {
89         return network;
90     }
91 
getEncapType()92     public int getEncapType() {
93         return encapType;
94     }
95 
getEncapLocalPort()96     public int getEncapLocalPort() {
97         return encapLocalPort;
98     }
99 
getEncapRemotePort()100     public int getEncapRemotePort() {
101         return encapRemotePort;
102     }
103 
getNattKeepaliveInterval()104     public int getNattKeepaliveInterval() {
105         return nattKeepaliveInterval;
106     }
107 
108     // Parcelable Methods
109 
110     @Override
describeContents()111     public int describeContents() {
112         return 0;
113     }
114 
115     @Override
writeToParcel(Parcel out, int flags)116     public void writeToParcel(Parcel out, int flags) {
117         // TODO: Use a byte array or other better method for storing IPs that can also include scope
118         out.writeString((localAddress != null) ? localAddress.getHostAddress() : null);
119         // TODO: Use a byte array or other better method for storing IPs that can also include scope
120         out.writeString((remoteAddress != null) ? remoteAddress.getHostAddress() : null);
121         out.writeParcelable(network, flags);
122         out.writeInt(flow[IpSecTransform.DIRECTION_IN].spi);
123         out.writeParcelable(flow[IpSecTransform.DIRECTION_IN].encryption, flags);
124         out.writeParcelable(flow[IpSecTransform.DIRECTION_IN].authentication, flags);
125         out.writeInt(flow[IpSecTransform.DIRECTION_OUT].spi);
126         out.writeParcelable(flow[IpSecTransform.DIRECTION_OUT].encryption, flags);
127         out.writeParcelable(flow[IpSecTransform.DIRECTION_OUT].authentication, flags);
128         out.writeInt(encapType);
129         out.writeInt(encapLocalPort);
130         out.writeInt(encapRemotePort);
131     }
132 
133     // Package Private: Used by the IpSecTransform.Builder;
134     // there should be no public constructor for this object
IpSecConfig()135     IpSecConfig() {}
136 
readInetAddressFromParcel(Parcel in)137     private static InetAddress readInetAddressFromParcel(Parcel in) {
138         String addrString = in.readString();
139         if (addrString == null) {
140             return null;
141         }
142         try {
143             return InetAddress.getByName(addrString);
144         } catch (UnknownHostException e) {
145             Log.wtf(TAG, "Invalid IpAddress " + addrString);
146             return null;
147         }
148     }
149 
IpSecConfig(Parcel in)150     private IpSecConfig(Parcel in) {
151         localAddress = readInetAddressFromParcel(in);
152         remoteAddress = readInetAddressFromParcel(in);
153         network = (Network) in.readParcelable(Network.class.getClassLoader());
154         flow[IpSecTransform.DIRECTION_IN].spi = in.readInt();
155         flow[IpSecTransform.DIRECTION_IN].encryption =
156                 (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
157         flow[IpSecTransform.DIRECTION_IN].authentication =
158                 (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
159         flow[IpSecTransform.DIRECTION_OUT].spi = in.readInt();
160         flow[IpSecTransform.DIRECTION_OUT].encryption =
161                 (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
162         flow[IpSecTransform.DIRECTION_OUT].authentication =
163                 (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
164         encapType = in.readInt();
165         encapLocalPort = in.readInt();
166         encapRemotePort = in.readInt();
167     }
168 
169     public static final Parcelable.Creator<IpSecConfig> CREATOR =
170             new Parcelable.Creator<IpSecConfig>() {
171                 public IpSecConfig createFromParcel(Parcel in) {
172                     return new IpSecConfig(in);
173                 }
174 
175                 public IpSecConfig[] newArray(int size) {
176                     return new IpSecConfig[size];
177                 }
178             };
179 }
180