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 android.annotation.IntRange; 20 import android.annotation.NonNull; 21 import android.annotation.SuppressLint; 22 import android.annotation.SystemApi; 23 import android.os.PersistableBundle; 24 25 import java.util.Objects; 26 27 /** 28 * TransportModeChildSessionParams represents proposed configurations for negotiating a transport 29 * mode Child Session. 30 */ 31 public final class TransportModeChildSessionParams extends ChildSessionParams { TransportModeChildSessionParams( IkeTrafficSelector[] inboundTs, IkeTrafficSelector[] outboundTs, ChildSaProposal[] proposals, int hardLifetimeSec, int softLifetimeSec)32 private TransportModeChildSessionParams( 33 IkeTrafficSelector[] inboundTs, 34 IkeTrafficSelector[] outboundTs, 35 ChildSaProposal[] proposals, 36 int hardLifetimeSec, 37 int softLifetimeSec) { 38 super( 39 inboundTs, 40 outboundTs, 41 proposals, 42 hardLifetimeSec, 43 softLifetimeSec, 44 true /*isTransport*/); 45 } 46 47 /** 48 * Constructs this object by deserializing a PersistableBundle * 49 * 50 * <p>Constructed TransportModeChildSessionParams is guaranteed to be valid, as checked by the 51 * TransportModeChildSessionParams.Builder 52 * 53 * @hide 54 */ 55 @NonNull fromPersistableBundle( @onNull PersistableBundle in)56 public static TransportModeChildSessionParams fromPersistableBundle( 57 @NonNull PersistableBundle in) { 58 Objects.requireNonNull(in, "PersistableBundle not provided"); 59 60 TransportModeChildSessionParams.Builder builder = 61 new TransportModeChildSessionParams.Builder(); 62 63 for (ChildSaProposal p : getProposalsFromPersistableBundle(in)) { 64 builder.addSaProposal(p); 65 } 66 67 for (IkeTrafficSelector ts : getTsFromPersistableBundle(in, INBOUND_TS_KEY)) { 68 builder.addInboundTrafficSelectors(ts); 69 } 70 71 for (IkeTrafficSelector ts : getTsFromPersistableBundle(in, OUTBOUND_TS_KEY)) { 72 builder.addOutboundTrafficSelectors(ts); 73 } 74 75 builder.setLifetimeSeconds( 76 in.getInt(HARD_LIFETIME_SEC_KEY), in.getInt(SOFT_LIFETIME_SEC_KEY)); 77 78 return builder.build(); 79 } 80 81 /** 82 * This class can be used to incrementally construct a {@link TransportModeChildSessionParams}. 83 */ 84 public static final class Builder extends ChildSessionParams.Builder { 85 /** Create a Builder for negotiating a transport mode Child Session. */ Builder()86 public Builder() { 87 super(); 88 } 89 90 /** 91 * Construct Builder from the {@link TransportModeChildSessionParams} object. 92 * 93 * @param childParams the object this Builder will be constructed with. 94 */ Builder(@onNull TransportModeChildSessionParams childParams)95 public Builder(@NonNull TransportModeChildSessionParams childParams) { 96 super(childParams); 97 } 98 99 /** 100 * Adds a Child SA proposal to the {@link TransportModeChildSessionParams} being built. 101 * 102 * @param proposal Child SA proposal. 103 * @return Builder this, to facilitate chaining. 104 * @deprecated Callers should use {@link #addChildSaProposal(ChildSaProposal)}. This method 105 * is deprecated because its name does not match the input type. 106 * @hide 107 */ 108 // The matching getter is defined in the super class. Please see 109 // {@link ChildSessionParams#getSaProposals} 110 @SuppressLint("MissingGetterMatchingBuilder") 111 @Deprecated 112 @SystemApi 113 @NonNull addSaProposal(@onNull ChildSaProposal proposal)114 public Builder addSaProposal(@NonNull ChildSaProposal proposal) { 115 return addChildSaProposal(proposal); 116 } 117 118 /** 119 * Adds a Child SA proposal to the {@link TransportModeChildSessionParams} being built. 120 * 121 * @param proposal Child SA proposal. 122 * @return Builder this, to facilitate chaining. 123 */ 124 // The matching getter is defined in the super class. Please see 125 // {@link ChildSessionParams#getSaProposals} 126 @SuppressLint("MissingGetterMatchingBuilder") 127 @NonNull addChildSaProposal(@onNull ChildSaProposal proposal)128 public Builder addChildSaProposal(@NonNull ChildSaProposal proposal) { 129 Objects.requireNonNull(proposal, "Required argument not provided"); 130 131 addProposal(proposal); 132 return this; 133 } 134 135 /** 136 * Adds an inbound {@link IkeTrafficSelector} to the {@link TransportModeChildSessionParams} 137 * being built. 138 * 139 * <p>This method allows callers to limit the inbound traffic transmitted over the Child 140 * Session to the given range. The IKE server may further narrow the range. Callers should 141 * refer to {@link ChildSessionConfiguration} for the negotiated traffic selectors. 142 * 143 * <p>If no inbound {@link IkeTrafficSelector} is provided, a default value will be used 144 * that covers all IP addresses and ports. 145 * 146 * @param trafficSelector the inbound {@link IkeTrafficSelector}. 147 * @return Builder this, to facilitate chaining. 148 */ 149 // The matching getter is defined in the super class. Please see {@link 150 // ChildSessionParams#getInboundTrafficSelectors} 151 @SuppressLint("MissingGetterMatchingBuilder") 152 @NonNull addInboundTrafficSelectors(@onNull IkeTrafficSelector trafficSelector)153 public Builder addInboundTrafficSelectors(@NonNull IkeTrafficSelector trafficSelector) { 154 Objects.requireNonNull(trafficSelector, "Required argument not provided"); 155 addInboundTs(trafficSelector); 156 return this; 157 } 158 159 /** 160 * Adds an outbound {@link IkeTrafficSelector} to the {@link 161 * TransportModeChildSessionParams} being built. 162 * 163 * <p>This method allows callers to limit the outbound traffic transmitted over the Child 164 * Session to the given range. The IKE server may further narrow the range. Callers should 165 * refer to {@link ChildSessionConfiguration} for the negotiated traffic selectors. 166 * 167 * <p>If no outbound {@link IkeTrafficSelector} is provided, a default value will be used 168 * that covers all IP addresses and ports. 169 * 170 * @param trafficSelector the outbound {@link IkeTrafficSelector}. 171 * @return Builder this, to facilitate chaining. 172 */ 173 // The matching getter is defined in the super class. Please see {@link 174 // ChildSessionParams#getOutboundTrafficSelectors} 175 @SuppressLint("MissingGetterMatchingBuilder") 176 @NonNull addOutboundTrafficSelectors(@onNull IkeTrafficSelector trafficSelector)177 public Builder addOutboundTrafficSelectors(@NonNull IkeTrafficSelector trafficSelector) { 178 Objects.requireNonNull(trafficSelector, "Required argument not provided"); 179 addOutboundTs(trafficSelector); 180 return this; 181 } 182 183 /** 184 * Sets hard and soft lifetimes. 185 * 186 * <p>Lifetimes will not be negotiated with the remote IKE server. 187 * 188 * @param hardLifetimeSeconds number of seconds after which Child SA will expire. Defaults 189 * to 7200 seconds (2 hours). Considering IPsec packet lifetime, IKE library requires 190 * hard lifetime to be a value from 300 seconds (5 minutes) to 14400 seconds (4 hours), 191 * inclusive. 192 * @param softLifetimeSeconds number of seconds after which Child SA will request rekey. 193 * Defaults to 3600 seconds (1 hour). MUST be at least 120 seconds (2 minutes), and at 194 * least 60 seconds (1 minute) shorter than the hard lifetime. 195 */ 196 // The matching getters are defined in the super class. Please see {@link 197 // ChildSessionParams#getHardLifetimeSeconds and {@link 198 // ChildSessionParams#getSoftLifetimeSeconds} 199 @SuppressLint("MissingGetterMatchingBuilder") 200 @NonNull setLifetimeSeconds( @ntRange from = CHILD_HARD_LIFETIME_SEC_MINIMUM, to = CHILD_HARD_LIFETIME_SEC_MAXIMUM) int hardLifetimeSeconds, @IntRange( from = CHILD_SOFT_LIFETIME_SEC_MINIMUM, to = CHILD_HARD_LIFETIME_SEC_MAXIMUM) int softLifetimeSeconds)201 public Builder setLifetimeSeconds( 202 @IntRange( 203 from = CHILD_HARD_LIFETIME_SEC_MINIMUM, 204 to = CHILD_HARD_LIFETIME_SEC_MAXIMUM) 205 int hardLifetimeSeconds, 206 @IntRange( 207 from = CHILD_SOFT_LIFETIME_SEC_MINIMUM, 208 to = CHILD_HARD_LIFETIME_SEC_MAXIMUM) 209 int softLifetimeSeconds) { 210 validateAndSetLifetime(hardLifetimeSeconds, softLifetimeSeconds); 211 mHardLifetimeSec = hardLifetimeSeconds; 212 mSoftLifetimeSec = softLifetimeSeconds; 213 return this; 214 } 215 216 /** 217 * Validates and builds the {@link TransportModeChildSessionParams}. 218 * 219 * @return the validated {@link TransportModeChildSessionParams}. 220 */ 221 @NonNull build()222 public TransportModeChildSessionParams build() { 223 addDefaultTsIfNotConfigured(); 224 validateOrThrow(); 225 226 return new TransportModeChildSessionParams( 227 mInboundTsList.toArray(new IkeTrafficSelector[0]), 228 mOutboundTsList.toArray(new IkeTrafficSelector[0]), 229 mSaProposalList.toArray(new ChildSaProposal[0]), 230 mHardLifetimeSec, 231 mSoftLifetimeSec); 232 } 233 } 234 } 235