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 package android.telephony.gba; 17 18 import android.annotation.IntDef; 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.SystemApi; 22 import android.os.Parcel; 23 import android.os.Parcelable; 24 import android.telephony.gba.TlsParams.TlsCipherSuite; 25 26 import java.lang.annotation.Retention; 27 import java.lang.annotation.RetentionPolicy; 28 import java.nio.ByteBuffer; 29 import java.util.Objects; 30 31 /** 32 * Description of ua security protocol identifier defined in 3GPP TS 33.220 H.2 33 * @hide 34 */ 35 @SystemApi 36 public final class UaSecurityProtocolIdentifier implements Parcelable { 37 38 /** 39 * Organization code defined in 3GPP TS 33.220 H.3 40 * 41 * @hide 42 */ 43 @Retention(RetentionPolicy.SOURCE) 44 @IntDef(prefix = {"ORG_"}, value = { 45 ORG_NONE, 46 ORG_3GPP, 47 ORG_3GPP2, 48 ORG_OMA, 49 ORG_GSMA, 50 ORG_LOCAL}) 51 public @interface OrganizationCode {} 52 53 /** 54 * Organization octet value for default ua security protocol 55 */ 56 public static final int ORG_NONE = 0; 57 /** 58 * Organization octet value for 3GPP ua security protocol 59 */ 60 public static final int ORG_3GPP = 0x01; 61 /** 62 * Organization octet value for 3GPP2 ua security protocol 63 */ 64 public static final int ORG_3GPP2 = 0x02; 65 /** 66 * Organization octet value for OMA ua security protocol 67 */ 68 public static final int ORG_OMA = 0x03; 69 /** 70 * Organization octet value for GSMA ua security protocol 71 */ 72 public static final int ORG_GSMA = 0x04; 73 /** 74 * Internal organization octet value for local/experimental protocols 75 */ 76 public static final int ORG_LOCAL = 0xFF; 77 78 /** 79 * 3GPP UA Security Protocol ID defined in 3GPP TS 33.220 H.3 80 * 81 * @hide 82 */ 83 @Retention(RetentionPolicy.SOURCE) 84 @IntDef(prefix = {"UA_SECURITY_PROTOCOL_3GPP_"}, value = { 85 UA_SECURITY_PROTOCOL_3GPP_SUBSCRIBER_CERTIFICATE, 86 UA_SECURITY_PROTOCOL_3GPP_MBMS, 87 UA_SECURITY_PROTOCOL_3GPP_HTTP_DIGEST_AUTHENTICATION, 88 UA_SECURITY_PROTOCOL_3GPP_HTTP_BASED_MBMS, 89 UA_SECURITY_PROTOCOL_3GPP_SIP_BASED_MBMS, 90 UA_SECURITY_PROTOCOL_3GPP_GENERIC_PUSH_LAYER, 91 UA_SECURITY_PROTOCOL_3GPP_IMS_MEDIA_PLANE, 92 UA_SECURITY_PROTOCOL_3GPP_GENERATION_TMPI, 93 UA_SECURITY_PROTOCOL_3GPP_TLS_DEFAULT, 94 UA_SECURITY_PROTOCOL_3GPP_TLS_BROWSER}) 95 public @interface UaSecurityProtocol3gpp {} 96 97 /** 98 * Security protocol param according to TS 33.221 as described in TS 99 * 33.220 Annex H. Mapped to byte stream "0x01,0x00,0x00,0x00,0x00". 100 */ 101 public static final int UA_SECURITY_PROTOCOL_3GPP_SUBSCRIBER_CERTIFICATE = 0; 102 103 /** 104 * Security protocol param according to TS 33.246 for Multimedia 105 * broadcast/Multimedia services (MBMS) as described in TS 106 * 33.220 Annex H. Mapped to byte stream "0x01,0x00,0x00,0x00,0x01". 107 */ 108 public static final int UA_SECURITY_PROTOCOL_3GPP_MBMS = 1; 109 110 /** 111 * Security protocol param based on HTTP digest authentication 112 * according to TS 24.109 as described in TS 33.220 Annex H. Mapped to 113 * byte stream "0x01,0x00,0x00,0x00,0x02". 114 */ 115 public static final int UA_SECURITY_PROTOCOL_3GPP_HTTP_DIGEST_AUTHENTICATION = 2; 116 117 /** 118 * Security protocol param used with HTTP-based security procedures for 119 * Multimedia broadcast/Multimedia services (MBMS) user services 120 * according to TS 26.237 as described in TS 33.220 Annex H. 121 * Mapped to byte stream "0x01,0x00,0x00,0x00,0x03". 122 */ 123 public static final int UA_SECURITY_PROTOCOL_3GPP_HTTP_BASED_MBMS = 3; 124 125 /** 126 * Security protocol param used with SIP-based security procedures for 127 * Multimedia broadcast/Multimedia services (MBMS) user services 128 * according to TS 26.237 as described in TS 33.220 Annex H. 129 * Mapped to byte stream "0x01,0x00,0x00,0x00,0x04". 130 */ 131 public static final int UA_SECURITY_PROTOCOL_3GPP_SIP_BASED_MBMS = 4; 132 133 /** 134 * Security protocol param used with Generic Push Layer according to TS 135 * 33.224 as described in TS 33.220 Annex H. Mapped to byte stream 136 * "0x01,0x00,0x00,0x00,0x05". 137 */ 138 public static final int UA_SECURITY_PROTOCOL_3GPP_GENERIC_PUSH_LAYER = 5; 139 140 /** 141 * Security protocol param used for IMS UE to KMS http based message 142 * exchanges according to "IMS media plane security", TS 33.328 as 143 * described in TS 33.220 Annex H. Mapped to byte stream 144 * "0x01,0x00,0x00,0x00,0x06". 145 */ 146 public static final int UA_SECURITY_PROTOCOL_3GPP_IMS_MEDIA_PLANE = 6; 147 148 /** 149 * Security protocol param used for Generation of Temporary IP 150 * Multimedia Private Identity (TMPI) according to TS 33.220 Annex B.4 151 * Mapped to byte stream "0x01,0x00,0x00,0x01,0x00". 152 */ 153 public static final int UA_SECURITY_PROTOCOL_3GPP_GENERATION_TMPI = 0x0100; 154 155 /** 156 * Security protocol param used for Shared key-based UE authentication with 157 * certificate-based NAF authentication, according to TS 33.222 section 5.3, 158 * or Shared key-based mutual authentication between UE and NAF, according to 159 * TS 33.222 section 5.4. Mapped to byte stream "0x01,0x00,0x01,yy,zz". 160 * "yy, zz" is the TLS CipherSuite code. 161 */ 162 public static final int UA_SECURITY_PROTOCOL_3GPP_TLS_DEFAULT = 0x010000; 163 164 /** 165 * Security protocol param used for Shared key-based UE authentication with 166 * certificate-based NAF authentication, according to TS 33.222 Annex D. 167 * Mapped to byte stream "0x01,0x00,0x02,yy,zz". 168 * "yy, zz" is the TLS CipherSuite code. 169 */ 170 public static final int UA_SECURITY_PROTOCOL_3GPP_TLS_BROWSER = 0x020000; 171 172 private static final int PROTOCOL_SIZE = 5; 173 private static final int[] sUaSp3gppIds = new int[] { 174 UA_SECURITY_PROTOCOL_3GPP_SUBSCRIBER_CERTIFICATE, 175 UA_SECURITY_PROTOCOL_3GPP_MBMS, 176 UA_SECURITY_PROTOCOL_3GPP_HTTP_DIGEST_AUTHENTICATION, 177 UA_SECURITY_PROTOCOL_3GPP_HTTP_BASED_MBMS, 178 UA_SECURITY_PROTOCOL_3GPP_SIP_BASED_MBMS, 179 UA_SECURITY_PROTOCOL_3GPP_GENERIC_PUSH_LAYER, 180 UA_SECURITY_PROTOCOL_3GPP_IMS_MEDIA_PLANE, 181 UA_SECURITY_PROTOCOL_3GPP_GENERATION_TMPI, 182 UA_SECURITY_PROTOCOL_3GPP_TLS_DEFAULT, 183 UA_SECURITY_PROTOCOL_3GPP_TLS_BROWSER}; 184 185 private int mOrg; 186 private int mProtocol; 187 private int mTlsCipherSuite; 188 UaSecurityProtocolIdentifier()189 private UaSecurityProtocolIdentifier() {} 190 UaSecurityProtocolIdentifier(UaSecurityProtocolIdentifier sp)191 private UaSecurityProtocolIdentifier(UaSecurityProtocolIdentifier sp) { 192 mOrg = sp.mOrg; 193 mProtocol = sp.mProtocol; 194 mTlsCipherSuite = sp.mTlsCipherSuite; 195 } 196 197 /** 198 * Returns the byte array representing the ua security protocol 199 */ 200 @NonNull toByteArray()201 public byte[] toByteArray() { 202 byte[] data = new byte[PROTOCOL_SIZE]; 203 ByteBuffer buf = ByteBuffer.wrap(data); 204 buf.put((byte) mOrg); 205 buf.putInt(mProtocol | mTlsCipherSuite); 206 return data; 207 } 208 209 /** 210 * Returns the organization code 211 */ getOrg()212 public @OrganizationCode int getOrg() { 213 return mOrg; 214 } 215 216 /** 217 * Returns the security procotol id 218 * 219 * <p>Note that only 3GPP UA Security Protocols are supported for now 220 */ getProtocol()221 public @UaSecurityProtocol3gpp int getProtocol() { 222 return mProtocol; 223 } 224 225 /** 226 * Returns the TLS cipher suite 227 */ getTlsCipherSuite()228 public @TlsCipherSuite int getTlsCipherSuite() { 229 return mTlsCipherSuite; 230 } 231 232 /** 233 * {@link Parcelable#writeToParcel} 234 */ 235 @Override writeToParcel(@onNull Parcel out, int flags)236 public void writeToParcel(@NonNull Parcel out, int flags) { 237 out.writeInt(mOrg); 238 out.writeInt(mProtocol); 239 out.writeInt(mTlsCipherSuite); 240 } 241 242 /** 243 * {@link Parcelable.Creator} 244 * 245 */ 246 public static final @NonNull Parcelable.Creator< 247 UaSecurityProtocolIdentifier> CREATOR = new Creator<UaSecurityProtocolIdentifier>() { 248 @Nullable 249 @Override 250 public UaSecurityProtocolIdentifier createFromParcel(Parcel in) { 251 int org = in.readInt(); 252 int protocol = in.readInt(); 253 int cs = in.readInt(); 254 if (org < 0 || protocol < 0 || cs < 0) { 255 return null; 256 } 257 Builder builder = new Builder(); 258 try { 259 if (org > 0) { 260 builder.setOrg(org); 261 } 262 if (protocol > 0) { 263 builder.setProtocol(protocol); 264 } 265 if (cs > 0) { 266 builder.setTlsCipherSuite(cs); 267 } 268 } catch (IllegalArgumentException e) { 269 return null; 270 } 271 return builder.build(); 272 } 273 274 @NonNull 275 @Override 276 public UaSecurityProtocolIdentifier[] newArray(int size) { 277 return new UaSecurityProtocolIdentifier[size]; 278 } 279 }; 280 281 /** 282 * {@link Parcelable#describeContents} 283 */ 284 @Override describeContents()285 public int describeContents() { 286 return 0; 287 } 288 289 @Override toString()290 public String toString() { 291 return "UaSecurityProtocolIdentifier[" + mOrg + " , " + (mProtocol | mTlsCipherSuite) + "]"; 292 } 293 294 @Override equals(Object obj)295 public boolean equals(Object obj) { 296 if (!(obj instanceof UaSecurityProtocolIdentifier)) { 297 return false; 298 } 299 300 UaSecurityProtocolIdentifier other = (UaSecurityProtocolIdentifier) obj; 301 302 return mOrg == other.mOrg && mProtocol == other.mProtocol 303 && mTlsCipherSuite == other.mTlsCipherSuite; 304 } 305 306 @Override hashCode()307 public int hashCode() { 308 return Objects.hash(mOrg, mProtocol, mTlsCipherSuite); 309 } 310 isTlsSupported()311 private boolean isTlsSupported() { 312 //TODO May update to support non 3gpp protocol in the future 313 if (mOrg == ORG_3GPP && (mProtocol == UA_SECURITY_PROTOCOL_3GPP_TLS_DEFAULT 314 || mProtocol == UA_SECURITY_PROTOCOL_3GPP_TLS_BROWSER)) { 315 return true; 316 } 317 318 return false; 319 } 320 321 /** 322 * Builder class for UaSecurityProtocolIdentifier 323 */ 324 public static final class Builder { 325 private final UaSecurityProtocolIdentifier mSp; 326 327 /** 328 * Creates a Builder with default UaSecurityProtocolIdentifier, a.k.a 0x00 00 00 00 00 329 */ Builder()330 public Builder() { 331 mSp = new UaSecurityProtocolIdentifier(); 332 } 333 334 /** 335 * Creates a Builder from a UaSecurityProtocolIdentifier 336 */ Builder(@onNull final UaSecurityProtocolIdentifier sp)337 public Builder(@NonNull final UaSecurityProtocolIdentifier sp) { 338 Objects.requireNonNull(sp); 339 mSp = new UaSecurityProtocolIdentifier(sp); 340 } 341 342 /** 343 * Sets the organization code 344 * 345 * @param orgCode the organization code with the following value 346 * <ol> 347 * <li>{@link #ORG_NONE} </li> 348 * <li>{@link #ORG_3GPP} </li> 349 * <li>{@link #ORG_3GPP2} </li> 350 * <li>{@link #ORG_OMA} </li> 351 * <li>{@link #ORG_GSMA} </li> 352 * <li>{@link #ORG_LOCAL} </li> 353 * </ol> 354 * @throws IllegalArgumentException if it is not one of the value above. 355 * 356 * <p>Note that this method will reset the security protocol and TLS cipher suite 357 * if they have been set. 358 */ 359 @NonNull setOrg(@rganizationCode int orgCode)360 public Builder setOrg(@OrganizationCode int orgCode) { 361 if (orgCode < ORG_NONE || orgCode > ORG_LOCAL) { 362 throw new IllegalArgumentException("illegal organization code"); 363 } 364 mSp.mOrg = orgCode; 365 mSp.mProtocol = 0; 366 mSp.mTlsCipherSuite = 0; 367 return this; 368 } 369 370 /** 371 * Sets the UA security protocol for 3GPP 372 * 373 * @param protocol only 3GPP ua security protocol ID is supported for now, which 374 * is one of the following value 375 * <ol> 376 * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_SUBSCRIBER_CERTIFICATE} </li> 377 * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_MBMS} </li> 378 * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_HTTP_DIGEST_AUTHENTICATION} </li> 379 * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_HTTP_BASED_MBMS} </li> 380 * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_SIP_BASED_MBMS} </li> 381 * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_GENERIC_PUSH_LAYER} </li> 382 * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_IMS_MEDIA_PLANE} </li> 383 * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_GENERATION_TMPI} </li> 384 * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_TLS_DEFAULT} </li> 385 * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_TLS_BROWSER} </li> 386 * </ol> 387 * @throws IllegalArgumentException if the protocol is not one of the value above. 388 * 389 * <p>Note that this method will reset TLS cipher suite if it has been set. 390 */ 391 @NonNull setProtocol(@aSecurityProtocol3gpp int protocol)392 public Builder setProtocol(@UaSecurityProtocol3gpp int protocol) { 393 //TODO May update to support non 3gpp protocol in the future 394 if (protocol < UA_SECURITY_PROTOCOL_3GPP_SUBSCRIBER_CERTIFICATE 395 || (protocol > UA_SECURITY_PROTOCOL_3GPP_IMS_MEDIA_PLANE 396 && protocol != UA_SECURITY_PROTOCOL_3GPP_GENERATION_TMPI 397 && protocol != UA_SECURITY_PROTOCOL_3GPP_TLS_DEFAULT 398 && protocol != UA_SECURITY_PROTOCOL_3GPP_TLS_BROWSER) 399 || mSp.mOrg != ORG_3GPP) { 400 throw new IllegalArgumentException("illegal protocol code"); 401 } 402 mSp.mProtocol = protocol; 403 mSp.mTlsCipherSuite = 0; 404 return this; 405 } 406 407 /** 408 * Sets the UA security protocol for 3GPP 409 * 410 * @param cs TLS cipher suite value defined by {@link TlsParams#TlsCipherSuite} 411 * @throws IllegalArgumentException if it is not a 3GPP ua security protocol, 412 * the protocol does not support TLS, or does not support the cipher suite. 413 */ 414 @NonNull setTlsCipherSuite(@lsCipherSuite int cs)415 public Builder setTlsCipherSuite(@TlsCipherSuite int cs) { 416 if (!mSp.isTlsSupported()) { 417 throw new IllegalArgumentException("The protocol does not support TLS"); 418 } 419 if (!TlsParams.isTlsCipherSuiteSupported(cs)) { 420 throw new IllegalArgumentException("TLS cipher suite is not supported"); 421 } 422 mSp.mTlsCipherSuite = cs; 423 return this; 424 } 425 426 /** 427 * Builds the instance of UaSecurityProtocolIdentifier 428 * 429 * @return the built instance of UaSecurityProtocolIdentifier 430 */ 431 @NonNull build()432 public UaSecurityProtocolIdentifier build() { 433 return new UaSecurityProtocolIdentifier(mSp); 434 } 435 } 436 } 437