• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 com.google.android.sample.rcsclient;
18 
19 import android.net.Uri;
20 import android.os.Bundle;
21 import android.os.Handler;
22 import android.os.Message;
23 import android.os.PersistableBundle;
24 import android.telephony.CarrierConfigManager;
25 import android.telephony.SmsManager;
26 import android.telephony.SubscriptionManager;
27 import android.telephony.TelephonyManager;
28 import android.telephony.TelephonyManager.BootstrapAuthenticationCallback;
29 import android.telephony.gba.UaSecurityProtocolIdentifier;
30 import android.text.method.ScrollingMovementMethod;
31 import android.util.Log;
32 import android.view.MenuItem;
33 import android.view.View;
34 import android.widget.AdapterView;
35 import android.widget.AdapterView.OnItemSelectedListener;
36 import android.widget.ArrayAdapter;
37 import android.widget.Button;
38 import android.widget.EditText;
39 import android.widget.Spinner;
40 import android.widget.TextView;
41 
42 import androidx.annotation.Nullable;
43 import androidx.appcompat.app.AppCompatActivity;
44 
45 import java.util.Locale;
46 import java.util.concurrent.ExecutorService;
47 import java.util.concurrent.Executors;
48 
49 /** An activity to verify GBA authentication. */
50 public class GbaActivity extends AppCompatActivity {
51 
52     private static final String TAG = "TestRcsApp.GbaActivity";
53     private static final String NAF_PREFIX = "https://3GPP-bootstrapping@";
54 
55     private static final int MSG_RESULT = 1;
56     private final ExecutorService mExecutorService = Executors.newSingleThreadExecutor();
57     private Button mGbaButton;
58     private TextView mCallbackResult;
59     private Spinner mOrganizationSpinner, mProtocolSpinner, mUiccSpinner;
60     private EditText mTlsCs;
61     private EditText mNaf;
62     private Handler mHandler;
63     private int mOrganization;
64     private int mProtocol;
65     private int mUiccType;
66 
bytesToHex(byte[] bytes)67     private static String bytesToHex(byte[] bytes) {
68         StringBuilder result = new StringBuilder();
69         for (byte aByte : bytes) {
70             result.append(String.format(Locale.US, "%02X", aByte));
71         }
72         return result.toString();
73     }
74 
75     @Override
onCreate(@ullable Bundle savedInstanceState)76     protected void onCreate(@Nullable Bundle savedInstanceState) {
77         super.onCreate(savedInstanceState);
78         setContentView(R.layout.gba_layout);
79 
80         getSupportActionBar().setDisplayHomeAsUpEnabled(true);
81         getSupportActionBar().setDisplayShowHomeEnabled(true);
82         initLayout();
83         mHandler = new Handler() {
84             public void handleMessage(Message message) {
85                 switch (message.what) {
86                     case MSG_RESULT:
87                         mCallbackResult.setText(message.obj.toString());
88                         break;
89                 }
90             }
91         };
92     }
93 
initLayout()94     private void initLayout() {
95         mGbaButton = findViewById(R.id.gba_btn);
96         mCallbackResult = findViewById(R.id.gba_result);
97         mCallbackResult.setMovementMethod(new ScrollingMovementMethod());
98         mTlsCs = findViewById(R.id.tls_id);
99         mNaf = findViewById(R.id.naf_url);
100 
101         initOrganization();
102         initProtocol();
103         initUicctype();
104 
105         int defaultSmsSubId = SmsManager.getDefaultSmsSubscriptionId();
106         if (!SubscriptionManager.isValidSubscriptionId(defaultSmsSubId)) {
107             Log.i(TAG, "invalid subId:" + defaultSmsSubId);
108             return;
109         }
110         TelephonyManager telephonyManager = getSystemService(
111                 TelephonyManager.class).createForSubscriptionId(defaultSmsSubId);
112         PersistableBundle carrierConfig = telephonyManager.getCarrierConfig();
113         String uploadUrl = carrierConfig.getString(
114                 CarrierConfigManager.KEY_CALL_COMPOSER_PICTURE_SERVER_URL_STRING);
115         mNaf.setText(NAF_PREFIX + uploadUrl);
116 
117         mGbaButton.setOnClickListener(view -> {
118             Log.i(TAG, "trigger bootstrapAuthenticationRequest");
119             UaSecurityProtocolIdentifier.Builder builder =
120                     new UaSecurityProtocolIdentifier.Builder();
121             try {
122                 builder.setOrg(mOrganization)
123                         .setProtocol(mProtocol)
124                         .setTlsCipherSuite(Integer.parseInt(mTlsCs.getText().toString()));
125             } catch (IllegalArgumentException e) {
126                 Log.e(TAG, e.getMessage());
127                 return;
128             }
129             UaSecurityProtocolIdentifier spId = builder.build();
130             telephonyManager.bootstrapAuthenticationRequest(mUiccType,
131                     Uri.parse(mNaf.getText().toString()),
132                     spId,
133                     true,
134                     mExecutorService,
135                     new BootstrapAuthenticationCallback() {
136                         @Override
137                         public void onKeysAvailable(byte[] gbaKey, String btId) {
138                             String result = "OnKeysAvailable key:" + bytesToHex(gbaKey)
139                                     + "\r\n btId:" + btId;
140                             Log.i(TAG, result);
141                             mHandler.sendMessage(mHandler.obtainMessage(MSG_RESULT, result));
142                         }
143 
144                         @Override
145                         public void onAuthenticationFailure(int reason) {
146                             String result = "OnAuthenticationFailure reason: " + reason;
147                             Log.i(TAG, result);
148                             mHandler.sendMessage(mHandler.obtainMessage(MSG_RESULT, result));
149                         }
150                     });
151         });
152     }
153 
initOrganization()154     private void initOrganization() {
155         mOrganizationSpinner = findViewById(R.id.organization_list);
156         ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
157                 R.array.organization, android.R.layout.simple_spinner_item);
158         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
159         mOrganizationSpinner.setAdapter(adapter);
160         mOrganizationSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
161             @Override
162             public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
163                 Log.i(TAG, "Organization position:" + position);
164                 switch (position) {
165                     case 0:
166                         mOrganization = UaSecurityProtocolIdentifier.ORG_NONE;
167                         break;
168                     case 1:
169                         mOrganization = UaSecurityProtocolIdentifier.ORG_3GPP;
170                         break;
171                     case 2:
172                         mOrganization = UaSecurityProtocolIdentifier.ORG_3GPP2;
173                         break;
174                     case 3:
175                         mOrganization = UaSecurityProtocolIdentifier.ORG_GSMA;
176                         break;
177                     case 4:
178                         mOrganization = UaSecurityProtocolIdentifier.ORG_LOCAL;
179                         break;
180                     default:
181                         Log.e(TAG, "invalid position:" + position);
182                 }
183             }
184 
185             @Override
186             public void onNothingSelected(AdapterView<?> parent) {
187                 // TODO Auto-generated method stub
188             }
189         });
190         mOrganizationSpinner.setSelection(1);
191     }
192 
initProtocol()193     private void initProtocol() {
194         mProtocolSpinner = findViewById(R.id.protocol_list);
195         ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
196                 R.array.protocol, android.R.layout.simple_spinner_item);
197         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
198         mProtocolSpinner.setAdapter(adapter);
199         mProtocolSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
200             @Override
201             public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
202                 Log.i(TAG, "Protocol position:" + position);
203                 switch (position) {
204                     case 0:
205                         mProtocol = UaSecurityProtocolIdentifier
206                                 .UA_SECURITY_PROTOCOL_3GPP_SUBSCRIBER_CERTIFICATE;
207                         break;
208                     case 1:
209                         mProtocol = UaSecurityProtocolIdentifier
210                                 .UA_SECURITY_PROTOCOL_3GPP_MBMS;
211                         break;
212                     case 2:
213                         mProtocol = UaSecurityProtocolIdentifier
214                                 .UA_SECURITY_PROTOCOL_3GPP_HTTP_DIGEST_AUTHENTICATION;
215                         break;
216                     case 3:
217                         mProtocol = UaSecurityProtocolIdentifier
218                                 .UA_SECURITY_PROTOCOL_3GPP_HTTP_BASED_MBMS;
219                         break;
220                     case 4:
221                         mProtocol = UaSecurityProtocolIdentifier
222                                 .UA_SECURITY_PROTOCOL_3GPP_SIP_BASED_MBMS;
223                         break;
224                     case 5:
225                         mProtocol = UaSecurityProtocolIdentifier
226                                 .UA_SECURITY_PROTOCOL_3GPP_GENERIC_PUSH_LAYER;
227                         break;
228                     case 6:
229                         mProtocol = UaSecurityProtocolIdentifier
230                                 .UA_SECURITY_PROTOCOL_3GPP_IMS_MEDIA_PLANE;
231                         break;
232                     case 7:
233                         mProtocol = UaSecurityProtocolIdentifier
234                                 .UA_SECURITY_PROTOCOL_3GPP_GENERATION_TMPI;
235                         break;
236                     case 8:
237                         mProtocol = UaSecurityProtocolIdentifier
238                                 .UA_SECURITY_PROTOCOL_3GPP_TLS_DEFAULT;
239                         break;
240                     case 9:
241                         mProtocol = UaSecurityProtocolIdentifier
242                                 .UA_SECURITY_PROTOCOL_3GPP_TLS_BROWSER;
243                         break;
244                     default:
245                         Log.e(TAG, "invalid position:" + position);
246                 }
247             }
248 
249             @Override
250             public void onNothingSelected(AdapterView<?> parent) {
251                 // TODO Auto-generated method stub
252             }
253         });
254         mProtocolSpinner.setSelection(8);
255     }
256 
initUicctype()257     private void initUicctype() {
258         mUiccSpinner = findViewById(R.id.uicc_list);
259         ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
260                 R.array.uicc_type, android.R.layout.simple_spinner_item);
261         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
262         mUiccSpinner.setAdapter(adapter);
263         mUiccSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
264             @Override
265             public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
266                 Log.i(TAG, "uicc position:" + position);
267                 switch (position) {
268                     case 0:
269                         mUiccType = TelephonyManager.APPTYPE_UNKNOWN;
270                         break;
271                     case 1:
272                         mUiccType = TelephonyManager.APPTYPE_SIM;
273                         break;
274                     case 2:
275                         mUiccType = TelephonyManager.APPTYPE_USIM;
276                         break;
277                     case 3:
278                         mUiccType = TelephonyManager.APPTYPE_RUIM;
279                         break;
280                     case 4:
281                         mUiccType = TelephonyManager.APPTYPE_CSIM;
282                         break;
283                     case 5:
284                         mUiccType = TelephonyManager.APPTYPE_ISIM;
285                         break;
286                     default:
287                         Log.e(TAG, "invalid position:" + position);
288                 }
289             }
290 
291             @Override
292             public void onNothingSelected(AdapterView<?> parent) {
293                 // TODO Auto-generated method stub
294             }
295         });
296         mUiccSpinner.setSelection(5);
297     }
298 
299     @Override
onOptionsItemSelected(MenuItem item)300     public boolean onOptionsItemSelected(MenuItem item) {
301         if (item.getItemId() == android.R.id.home) {
302             finish();
303         }
304         return super.onOptionsItemSelected(item);
305     }
306 }
307