1 /* 2 * Copyright (C) 2020 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.ike3gpp; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.SuppressLint; 22 import android.annotation.SystemApi; 23 24 import com.android.internal.net.ipsec.ike.ike3gpp.Ike3gppDeviceIdentityUtils; 25 26 import java.util.Objects; 27 28 /** 29 * Ike3gppParams is used to configure 3GPP-specific parameters to be used during an IKE Session. 30 * 31 * @see 3GPP ETSI TS 24.302: Access to the 3GPP Evolved Packet Core (EPC) via non-3GPP access 32 * networks 33 * @hide 34 */ 35 @SystemApi 36 public final class Ike3gppParams { 37 /** If the PDU Session ID is not set, it will be reported as 0. */ 38 // NoByteOrShort: using byte to be consistent with the PDU Session ID specification 39 @SuppressLint("NoByteOrShort") 40 public static final byte PDU_SESSION_ID_UNSET = 0; 41 42 private final byte mPduSessionId; 43 private final String mDeviceIdentity; 44 Ike3gppParams(byte pduSessionId, @Nullable String deviceIdentity)45 private Ike3gppParams(byte pduSessionId, @Nullable String deviceIdentity) { 46 mPduSessionId = pduSessionId; 47 mDeviceIdentity = deviceIdentity; 48 } 49 50 /** 51 * Retrieves the PDU Session ID for this Ike3gppParams. 52 * 53 * <p>If the PDU Session ID was not set and this method is called, {@link PDU_SESSION_ID_UNSET} 54 * will be returned. 55 */ 56 // NoByteOrShort: using byte to be consistent with the PDU Session ID specification 57 @SuppressLint("NoByteOrShort") getPduSessionId()58 public byte getPduSessionId() { 59 return mPduSessionId; 60 } 61 62 /** 63 * Returns true if the PDU Session ID is set for this instance. 64 * 65 * @hide 66 */ hasPduSessionId()67 public boolean hasPduSessionId() { 68 return mPduSessionId != PDU_SESSION_ID_UNSET; 69 } 70 71 /** 72 * Retrieves the Device Identity for this Ike3gppParams. 73 * 74 * <p>If the Device Identity was not set and this method is called, null is returned 75 */ getMobileDeviceIdentity()76 public @Nullable String getMobileDeviceIdentity() { 77 return mDeviceIdentity; 78 } 79 80 @Override hashCode()81 public int hashCode() { 82 return Objects.hash(mPduSessionId, mDeviceIdentity); 83 } 84 85 @Override equals(Object o)86 public boolean equals(Object o) { 87 if (this == o) return true; 88 if (!(o instanceof Ike3gppParams)) return false; 89 90 Ike3gppParams that = (Ike3gppParams) o; 91 return ((mPduSessionId == that.mPduSessionId) 92 && Objects.equals(mDeviceIdentity, that.mDeviceIdentity)); 93 } 94 95 @Override toString()96 public String toString() { 97 return new StringBuilder() 98 .append("Ike3gppParams={ ") 99 .append("pduSessionId=") 100 .append(String.format("%02X", mPduSessionId)) 101 .append(String.format("%16s", mDeviceIdentity)) 102 .append(" }") 103 .toString(); 104 } 105 106 /** This class can be used to incrementally construct an {@link Ike3gppParams}. */ 107 public static final class Builder { 108 private byte mPduSessionId = PDU_SESSION_ID_UNSET; 109 private String mDeviceIdentity; 110 111 /** 112 * Sets the PDU Session ID to be used for the 3GPP N1_MODE_CAPABILITY payload. 113 * 114 * <p>Setting the PDU Session ID will configure the IKE Session to notify the server that it 115 * supports N1_MODE. 116 * 117 * <p>{@link PDU_SESSION_ID_UNSET} will clear the previously-set PDU Session ID. 118 * 119 * @see TS 24.007 Section 11.2.3.1b for the definition of PDU Session ID encoding 120 * @see TS 24.302 Section 7.2.2 for context on PDU Session ID usage 121 * @see TS 24.302 Section 8.2.9.15 for a description of the N1_MODE_CAPABILITY payload 122 * @param pduSessionId the PDU Session ID value to be used in this IKE Session 123 * @return Builder this, to facilitate chaining 124 */ 125 // NoByteOrShort: using byte to be consistent with the PDU Session ID specification 126 @NonNull setPduSessionId(@uppressLint"NoByteOrShort") byte pduSessionId)127 public Builder setPduSessionId(@SuppressLint("NoByteOrShort") byte pduSessionId) { 128 mPduSessionId = pduSessionId; 129 return this; 130 } 131 132 /** 133 * Setting the device identity (IMEI or IMEISV) will enable Mobile Device Identity 134 * Signalling support. 135 * 136 * @see 3GPP 24.302 Section 7.2.6 for details of signaling exchange 137 * @param deviceIdentity String representing decimal digits of IMEI(SV). IMEI is 15 digits 138 * and IMEISV is 16 digits long as per spec 3GPP TS 23.300. The implementation infers 139 * the Identity Type (IMEI or IMEISV) based on the length of the deviceIdentity passed 140 * in. A string of invalid length will result in an exception during build(). If the 141 * device identity is set, EAP-AKA MUST be configured to be an acceptable auth method. 142 * Device identity can be unset by passing null. 143 * @return Builder this, to facilitate chaining 144 */ 145 @NonNull setMobileDeviceIdentity(@ullable String deviceIdentity)146 public Builder setMobileDeviceIdentity(@Nullable String deviceIdentity) { 147 mDeviceIdentity = deviceIdentity; 148 return this; 149 } 150 151 /** 152 * Validates and builds the {@link Ike3gppParams}. 153 * 154 * @return Ike3gppParams the validated Ike3gppParams 155 */ 156 @NonNull build()157 public Ike3gppParams build() { 158 if (mDeviceIdentity != null) { 159 if (!Ike3gppDeviceIdentityUtils.isValidDeviceIdentity(mDeviceIdentity)) { 160 throw new IllegalArgumentException( 161 "valid device identity should be 15 or 16 digits or set to null"); 162 } 163 } 164 return new Ike3gppParams(mPduSessionId, mDeviceIdentity); 165 } 166 } 167 } 168