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 */
16package android.net;
17
18import android.os.Parcel;
19import android.os.Parcelable;
20import android.util.Log;
21import java.net.InetAddress;
22import java.net.UnknownHostException;
23
24/** @hide */
25public 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
64    public int getMode() {
65        return mode;
66    }
67
68    public InetAddress getLocalAddress() {
69        return localAddress;
70    }
71
72    public int getSpi(int direction) {
73        return flow[direction].spi;
74    }
75
76    public InetAddress getRemoteAddress() {
77        return remoteAddress;
78    }
79
80    public IpSecAlgorithm getEncryption(int direction) {
81        return flow[direction].encryption;
82    }
83
84    public IpSecAlgorithm getAuthentication(int direction) {
85        return flow[direction].authentication;
86    }
87
88    public Network getNetwork() {
89        return network;
90    }
91
92    public int getEncapType() {
93        return encapType;
94    }
95
96    public int getEncapLocalPort() {
97        return encapLocalPort;
98    }
99
100    public int getEncapRemotePort() {
101        return encapRemotePort;
102    }
103
104    public int getNattKeepaliveInterval() {
105        return nattKeepaliveInterval;
106    }
107
108    // Parcelable Methods
109
110    @Override
111    public int describeContents() {
112        return 0;
113    }
114
115    @Override
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
135    IpSecConfig() {}
136
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
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