• 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 package com.android.internal.net.ipsec.ike.ike3gpp;
17 
18 import static android.net.ipsec.ike.IkeManager.getIkeLog;
19 import static android.net.ipsec.ike.ike3gpp.Ike3gppBackoffTimer.isValidErrorNotifyCause;
20 
21 import static com.android.internal.net.ipsec.ike.ike3gpp.Ike3gppExtensionExchange.NOTIFY_TYPE_BACKOFF_TIMER;
22 import static com.android.internal.net.ipsec.ike.ike3gpp.Ike3gppExtensionExchange.NOTIFY_TYPE_DEVICE_IDENTITY;
23 import static com.android.internal.net.ipsec.ike.ike3gpp.Ike3gppExtensionExchange.NOTIFY_TYPE_N1_MODE_INFORMATION;
24 
25 import android.annotation.NonNull;
26 import android.net.ipsec.ike.exceptions.InvalidSyntaxException;
27 import android.net.ipsec.ike.ike3gpp.Ike3gppBackoffTimer;
28 import android.net.ipsec.ike.ike3gpp.Ike3gppData;
29 import android.net.ipsec.ike.ike3gpp.Ike3gppExtension;
30 import android.net.ipsec.ike.ike3gpp.Ike3gppN1ModeInformation;
31 import android.util.ArraySet;
32 
33 import com.android.internal.net.ipsec.ike.message.IkeNotifyPayload;
34 import com.android.internal.net.ipsec.ike.message.IkePayload;
35 
36 import java.util.ArrayList;
37 import java.util.List;
38 import java.util.Set;
39 import java.util.concurrent.Executor;
40 
41 /**
42  * Ike3gppIkeAuth contains the implementation for IKE_AUTH 3GPP-specific functionality in IKEv2.
43  *
44  * <p>This class is package-private.
45  */
46 class Ike3gppIkeAuth extends Ike3gppExchangeBase {
47     private static final String TAG = Ike3gppIkeAuth.class.getSimpleName();
48     private static final Set<Integer> SUPPORTED_RESPONSE_NOTIFY_TYPES = new ArraySet<>();
49     private boolean mIsDeviceIdentityRequestedByNetwork;
50 
51     static {
52         SUPPORTED_RESPONSE_NOTIFY_TYPES.add(NOTIFY_TYPE_N1_MODE_INFORMATION);
53         SUPPORTED_RESPONSE_NOTIFY_TYPES.add(NOTIFY_TYPE_BACKOFF_TIMER);
54         SUPPORTED_RESPONSE_NOTIFY_TYPES.add(NOTIFY_TYPE_DEVICE_IDENTITY);
55     }
56 
57     /** Initializes an Ike3gppIkeAuth. */
Ike3gppIkeAuth(@onNull Ike3gppExtension ike3gppExtension, @NonNull Executor userCbExecutor)58     Ike3gppIkeAuth(@NonNull Ike3gppExtension ike3gppExtension, @NonNull Executor userCbExecutor) {
59         super(ike3gppExtension, userCbExecutor);
60     }
61 
62     /** Provides a list of 3GPP payloads to add in the outbound EAP AUTH REQ. */
getRequestPayloadsInEap(boolean serverAuthenticated)63     List<IkePayload> getRequestPayloadsInEap(boolean serverAuthenticated) {
64         List<IkePayload> ike3gppPayloads = new ArrayList<>();
65 
66         if (mIsDeviceIdentityRequestedByNetwork && serverAuthenticated) {
67             String deviceIdentity = mIke3gppExtension.getIke3gppParams().getMobileDeviceIdentity();
68             if (deviceIdentity != null) {
69                 ike3gppPayloads.add(
70                         Ike3gppDeviceIdentityUtils.generateDeviceIdentityPayload(deviceIdentity));
71             }
72         }
73         return ike3gppPayloads;
74     }
75 
getRequestPayloads()76     List<IkePayload> getRequestPayloads() {
77         List<IkePayload> ike3gppPayloads = new ArrayList<>();
78         if (mIke3gppExtension.getIke3gppParams().hasPduSessionId()) {
79             ike3gppPayloads.add(
80                     Ike3gppN1ModeUtils.generateN1ModeCapabilityPayload(
81                             mIke3gppExtension.getIke3gppParams().getPduSessionId()));
82         }
83 
84         return ike3gppPayloads;
85     }
86 
extract3gppResponsePayloads(List<IkePayload> payloads)87     List<IkePayload> extract3gppResponsePayloads(List<IkePayload> payloads) {
88         List<IkePayload> ike3gppPayloads = new ArrayList<>();
89 
90         for (IkePayload payload : payloads) {
91             switch (payload.payloadType) {
92                 case IkePayload.PAYLOAD_TYPE_NOTIFY:
93                     IkeNotifyPayload notifyPayload = (IkeNotifyPayload) payload;
94                     if (SUPPORTED_RESPONSE_NOTIFY_TYPES.contains(notifyPayload.notifyType)
95                             || isValidErrorNotifyCause(notifyPayload)) {
96                         ike3gppPayloads.add(notifyPayload);
97                     }
98                     break;
99                 default:
100                     // not a 3GPP-specific payload
101                     break;
102             }
103         }
104 
105         return ike3gppPayloads;
106     }
107 
handleAuthResp(List<IkePayload> ike3gppPayloads)108     void handleAuthResp(List<IkePayload> ike3gppPayloads) throws InvalidSyntaxException {
109         List<Ike3gppData> ike3gppDataList = new ArrayList<>();
110         List<IkeNotifyPayload> notifyPayloads =
111                 IkePayload.getPayloadListForTypeInProvidedList(
112                         IkePayload.PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class, ike3gppPayloads);
113 
114         IkeNotifyPayload backoffTimerPayload = null;
115         IkeNotifyPayload backoffTimerCause = null;
116         for (IkeNotifyPayload notifyPayload : notifyPayloads) {
117             switch (notifyPayload.notifyType) {
118                 case NOTIFY_TYPE_N1_MODE_INFORMATION:
119                     // N1_MODE_CAPABILITY must be configured for the client to be notified
120                     if (!mIke3gppExtension.getIke3gppParams().hasPduSessionId()) {
121                         logw("Received N1_MODE_INFORMATION when N1 Mode is not enabled");
122                         continue;
123                     }
124 
125                     byte[] snssai =
126                             Ike3gppN1ModeUtils.getSnssaiFromNotifyData(notifyPayload.notifyData);
127                     ike3gppDataList.add(new Ike3gppN1ModeInformation(snssai));
128                     break;
129                 case NOTIFY_TYPE_BACKOFF_TIMER:
130                     backoffTimerPayload = notifyPayload;
131                     break;
132                 case NOTIFY_TYPE_DEVICE_IDENTITY:
133                     mIsDeviceIdentityRequestedByNetwork = true;
134                     break;
135                 default:
136                     if (isValidErrorNotifyCause(notifyPayload)) {
137                         if (backoffTimerCause == null) {
138                             backoffTimerCause = notifyPayload;
139                         }
140                     } else {
141                         // non-3GPP payload. Can be ignored.
142                         logd(
143                                 "Non-3GPP payload processed as 3GPP: "
144                                         + notifyPayload.getTypeString());
145                     }
146                     break;
147             }
148         }
149 
150         if (backoffTimerPayload != null && backoffTimerCause != null) {
151             byte backoffTimer =
152                     Ike3gppBackoffTimerUtils.getBackoffTimerfromNotifyData(
153                             backoffTimerPayload.notifyData);
154             ike3gppDataList.add(
155                     new Ike3gppBackoffTimer(backoffTimer, backoffTimerCause.notifyType));
156         } else if (backoffTimerPayload != null) {
157             logw("Received BACKOFF_TIMER payload without an Error-Notify");
158         }
159 
160         maybeInvokeUserCallback(ike3gppDataList);
161     }
162 
logd(String msg)163     private void logd(String msg) {
164         getIkeLog().d(TAG, msg);
165     }
166 
logw(String msg)167     private void logw(String msg) {
168         getIkeLog().w(TAG, msg);
169     }
170 }
171