1 /* 2 * Copyright (C) 2019 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 17 package android.net.ipsec.ike; 18 19 import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_APPLICATION_VERSION; 20 import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_IP4_PCSCF; 21 import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_IP6_PCSCF; 22 23 import android.annotation.IntDef; 24 import android.annotation.NonNull; 25 import android.annotation.SystemApi; 26 27 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload; 28 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttribute; 29 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeAppVersion; 30 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Pcscf; 31 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv6Pcscf; 32 33 import java.lang.annotation.Retention; 34 import java.lang.annotation.RetentionPolicy; 35 import java.net.InetAddress; 36 import java.util.ArrayList; 37 import java.util.Collections; 38 import java.util.HashSet; 39 import java.util.List; 40 import java.util.Objects; 41 import java.util.Set; 42 43 /** 44 * IkeSessionConfiguration represents the negotiated configuration for a {@link IkeSession}. 45 * 46 * <p>Configurations include remote application version and enabled IKE extensions.. 47 * 48 * @hide 49 */ 50 @SystemApi 51 public final class IkeSessionConfiguration { 52 /** @hide */ 53 @Retention(RetentionPolicy.SOURCE) 54 @IntDef({EXTENSION_TYPE_FRAGMENTATION, EXTENSION_TYPE_MOBIKE}) 55 public @interface ExtensionType {} 56 57 /** IKE Message Fragmentation */ 58 public static final int EXTENSION_TYPE_FRAGMENTATION = 1; 59 /** IKEv2 Mobility and Multihoming Protocol */ 60 public static final int EXTENSION_TYPE_MOBIKE = 2; 61 62 private final String mRemoteApplicationVersion; 63 private final IkeSessionConnectionInfo mIkeConnInfo; 64 private final List<InetAddress> mPcscfServers = new ArrayList<>(); 65 private final List<byte[]> mRemoteVendorIds = new ArrayList<>(); 66 private final Set<Integer> mEnabledExtensions = new HashSet<>(); 67 68 /** 69 * Construct an instance of {@link IkeSessionConfiguration}. 70 * 71 * <p>IkeSessionConfigurations may only be built with a with a Configure(Reply) Payload. 72 * 73 * @hide 74 */ IkeSessionConfiguration( IkeSessionConnectionInfo ikeConnInfo, IkeConfigPayload configPayload, List<byte[]> remoteVendorIds, List<Integer> enabledExtensions)75 public IkeSessionConfiguration( 76 IkeSessionConnectionInfo ikeConnInfo, 77 IkeConfigPayload configPayload, 78 List<byte[]> remoteVendorIds, 79 List<Integer> enabledExtensions) { 80 String errMsg = " not provided"; 81 Objects.requireNonNull(ikeConnInfo, "ikeConnInfo" + errMsg); 82 Objects.requireNonNull(remoteVendorIds, "remoteVendorIds" + errMsg); 83 Objects.requireNonNull(enabledExtensions, "enabledExtensions" + errMsg); 84 85 mIkeConnInfo = ikeConnInfo; 86 mRemoteVendorIds.addAll(remoteVendorIds); 87 mEnabledExtensions.addAll(enabledExtensions); 88 89 String appVersion = ""; 90 if (configPayload != null) { 91 if (configPayload.configType != IkeConfigPayload.CONFIG_TYPE_REPLY) { 92 throw new IllegalArgumentException( 93 "Cannot build IkeSessionConfiguration with configuration type: " 94 + configPayload.configType); 95 } 96 97 for (ConfigAttribute attr : configPayload.recognizedAttributeList) { 98 if (attr.isEmptyValue()) continue; 99 switch (attr.attributeType) { 100 case CONFIG_ATTR_APPLICATION_VERSION: 101 ConfigAttributeAppVersion appVersionAttr = (ConfigAttributeAppVersion) attr; 102 appVersion = appVersionAttr.applicationVersion; 103 break; 104 case CONFIG_ATTR_IP4_PCSCF: 105 ConfigAttributeIpv4Pcscf ip4Pcscf = (ConfigAttributeIpv4Pcscf) attr; 106 mPcscfServers.add(ip4Pcscf.getAddress()); 107 break; 108 case CONFIG_ATTR_IP6_PCSCF: 109 ConfigAttributeIpv6Pcscf ip6Pcscf = (ConfigAttributeIpv6Pcscf) attr; 110 mPcscfServers.add(ip6Pcscf.getAddress()); 111 break; 112 default: 113 // Not relevant to IKE session 114 } 115 } 116 } 117 mRemoteApplicationVersion = appVersion; 118 } 119 120 /** 121 * Gets remote (server) version information. 122 * 123 * @return application version of the remote server, or an empty string if the remote server did 124 * not provide the application version. 125 */ 126 @NonNull getRemoteApplicationVersion()127 public String getRemoteApplicationVersion() { 128 return mRemoteApplicationVersion; 129 } 130 131 /** 132 * Returns remote vendor IDs received during IKE Session setup. 133 * 134 * @return the vendor IDs of the remote server, or an empty list if no vendor ID is received 135 * during IKE Session setup. 136 */ 137 @NonNull getRemoteVendorIds()138 public List<byte[]> getRemoteVendorIds() { 139 return Collections.unmodifiableList(mRemoteVendorIds); 140 } 141 142 /** 143 * Checks if an IKE extension is enabled. 144 * 145 * <p>An IKE extension is enabled when both sides can support it. This negotiation always 146 * happens in IKE initial exchanges (IKE INIT and IKE AUTH). 147 * 148 * @param extensionType the extension type. 149 * @return {@code true} if this extension is enabled. 150 */ isIkeExtensionEnabled(@xtensionType int extensionType)151 public boolean isIkeExtensionEnabled(@ExtensionType int extensionType) { 152 return mEnabledExtensions.contains(extensionType); 153 } 154 155 /** 156 * Returns the assigned P_CSCF servers. 157 * 158 * @return the assigned P_CSCF servers, or an empty list when no servers are assigned by the 159 * remote IKE server 160 */ 161 @NonNull getPcscfServers()162 public List<InetAddress> getPcscfServers() { 163 return Collections.unmodifiableList(mPcscfServers); 164 } 165 166 /** 167 * Returns the connection information. 168 * 169 * @return the IKE Session connection information. 170 */ 171 @NonNull getIkeSessionConnectionInfo()172 public IkeSessionConnectionInfo getIkeSessionConnectionInfo() { 173 return mIkeConnInfo; 174 } 175 } 176