diff options
Diffstat (limited to 'src/java/android/net/ipsec')
23 files changed, 0 insertions, 3320 deletions
diff --git a/src/java/android/net/ipsec/ike/ChildSaProposal.java b/src/java/android/net/ipsec/ike/ChildSaProposal.java deleted file mode 100644 index c8851a71..00000000 --- a/src/java/android/net/ipsec/ike/ChildSaProposal.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.ipsec.ike; - -import com.android.internal.net.ipsec.ike.message.IkePayload; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.DhGroupTransform; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EncryptionTransform; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EsnTransform; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IntegrityTransform; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.Transform; - -import java.util.Arrays; -import java.util.List; - -/** - * ChildSaProposal represents a user configured set contains cryptograhic algorithms and key - * generating materials for negotiating an Child SA. - * - * <p>User must provide at least a valid ChildSaProposal when they are creating a new Child SA. - * - * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key Exchange - * Protocol Version 2 (IKEv2)</a> - */ -public final class ChildSaProposal extends SaProposal { - private final EsnTransform[] mEsns; - - /** - * Construct an instance of ChildSaProposal. - * - * <p>This constructor is either called by ChildSaPayload for building an inbound proposal from - * a decoded packet, or called by the inner Builder to build an outbound proposal from user - * provided parameters - * - * @param encryptionAlgos encryption algorithms - * @param integrityAlgos integrity algorithms - * @param dhGroups Diffie-Hellman Groups - * @param esns ESN policies - */ - public ChildSaProposal( - EncryptionTransform[] encryptionAlgos, - IntegrityTransform[] integrityAlgos, - DhGroupTransform[] dhGroups, - EsnTransform[] esns) { - super(IkePayload.PROTOCOL_ID_ESP, encryptionAlgos, integrityAlgos, dhGroups); - mEsns = esns; - } - - /** Gets all ESN policies. */ - public EsnTransform[] getEsnTransforms() { - return mEsns; - } - - /** - * Gets a copy of proposal without all proposed DH groups. - * - * <p>This is used to avoid negotiating DH Group for negotiating first Child SA. - */ - public ChildSaProposal getCopyWithoutDhTransform() { - return new ChildSaProposal( - getEncryptionTransforms(), - getIntegrityTransforms(), - new DhGroupTransform[0], - getEsnTransforms()); - } - - @Override - public Transform[] getAllTransforms() { - List<Transform> transformList = getAllTransformsAsList(); - transformList.addAll(Arrays.asList(mEsns)); - - return transformList.toArray(new Transform[transformList.size()]); - } - - @Override - public boolean isNegotiatedFrom(SaProposal reqProposal) { - return super.isNegotiatedFrom(reqProposal) - && isTransformSelectedFrom(mEsns, ((ChildSaProposal) reqProposal).mEsns); - } - - /** - * This class can be used to incrementally construct a ChildSaProposal. ChildSaProposal - * instances are immutable once built. - * - * <p>TODO: Support users to add algorithms from most preferred to least preferred. - */ - public static final class Builder extends SaProposal.Builder { - /** - * Adds an encryption algorithm with specific key length to SA proposal being built. - * - * @param algorithm encryption algorithm to add to ChildSaProposal. - * @param keyLength key length of algorithm. For algorithm that has fixed key length (e.g. - * 3DES) only KEY_LEN_UNUSED is allowed. - * @return Builder of ChildSaProposal. - * @throws IllegalArgumentException if AEAD and non-combined mode algorithms are mixed. - */ - public Builder addEncryptionAlgorithm(@EncryptionAlgorithm int algorithm, int keyLength) { - validateAndAddEncryptAlgo(algorithm, keyLength); - return this; - } - - /** - * Adds an integrity algorithm to SA proposal being built. - * - * @param algorithm integrity algorithm to add to ChildSaProposal. - * @return Builder of ChildSaProposal. - */ - public Builder addIntegrityAlgorithm(@IntegrityAlgorithm int algorithm) { - addIntegrityAlgo(algorithm); - return this; - } - - /** - * Adds a Diffie-Hellman Group to SA proposal being built. - * - * @param dhGroup to add to ChildSaProposal. - * @return Builder of ChildSaProposal. - */ - public Builder addDhGroup(@DhGroup int dhGroup) { - addDh(dhGroup); - return this; - } - - private IntegrityTransform[] buildIntegAlgosOrThrow() { - // When building Child SA Proposal with normal-mode ciphers, there is no contraint on - // integrity algorithm. When building Child SA Proposal with combined-mode ciphers, - // mProposedIntegrityAlgos must be either empty or only have INTEGRITY_ALGORITHM_NONE. - for (IntegrityTransform transform : mProposedIntegrityAlgos) { - if (transform.id != INTEGRITY_ALGORITHM_NONE && mHasAead) { - throw new IllegalArgumentException( - ERROR_TAG - + "Only INTEGRITY_ALGORITHM_NONE can be" - + " proposed with combined-mode ciphers in any proposal."); - } - } - - return mProposedIntegrityAlgos.toArray( - new IntegrityTransform[mProposedIntegrityAlgos.size()]); - } - - /** - * Validates, builds and returns the ChildSaProposal - * - * @return the validated ChildSaProposal. - * @throws IllegalArgumentException if ChildSaProposal is invalid. - */ - public ChildSaProposal build() { - EncryptionTransform[] encryptionTransforms = buildEncryptAlgosOrThrow(); - IntegrityTransform[] integrityTransforms = buildIntegAlgosOrThrow(); - - return new ChildSaProposal( - encryptionTransforms, - integrityTransforms, - mProposedDhGroups.toArray(new DhGroupTransform[mProposedDhGroups.size()]), - new EsnTransform[] {new EsnTransform()}); - } - } -} diff --git a/src/java/android/net/ipsec/ike/ChildSessionCallback.java b/src/java/android/net/ipsec/ike/ChildSessionCallback.java deleted file mode 100644 index ec8722e6..00000000 --- a/src/java/android/net/ipsec/ike/ChildSessionCallback.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.ipsec.ike; - -import android.net.IpSecManager.PolicyDirection; -import android.net.IpSecTransform; -import android.net.ipsec.ike.exceptions.IkeException; - -/** Callback interface for receiving state changes of a Child Session. */ -public interface ChildSessionCallback { - /** - * Called when Child Session setup succeeds. - * - * @param sessionConfiguration the configuration information of Child Session negotiated during - * Child creation. - */ - void onOpened(ChildSessionConfiguration sessionConfiguration); - - /** - * Called when either side has decided to close this Session and the deletion exchange - * finishes. - * - * <p>This method will not be fired if this deletion is caused by a fatal error. - */ - void onClosed(); - - /** - * Called if Child Session setup fails or Child Session is closed because of a fatal error. - * - * @param exception the detailed error. - */ - void onClosedExceptionally(IkeException exception); - - /** - * Called when a new {@link IpSecTransform} is created for this Child Session. - * - * @param ipSecTransform the created {@link IpSecTransform} - * @param direction the direction of this {@link IpSecTransform} - */ - void onIpSecTransformCreated(IpSecTransform ipSecTransform, @PolicyDirection int direction); - - /** - * Called when a new {@link IpSecTransform} is deleted for this Child Session. - * - * <p>Users MUST remove the transform from the socket or interface. Otherwise the communication - * on that socket or interface will fail. - * - * @param ipSecTransform the deleted {@link IpSecTransform} - * @param direction the direction of this {@link IpSecTransform} - */ - void onIpSecTransformDeleted(IpSecTransform ipSecTransform, @PolicyDirection int direction); -} diff --git a/src/java/android/net/ipsec/ike/ChildSessionConfiguration.java b/src/java/android/net/ipsec/ike/ChildSessionConfiguration.java deleted file mode 100644 index 2ed9de2f..00000000 --- a/src/java/android/net/ipsec/ike/ChildSessionConfiguration.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.ipsec.ike; - -import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_ADDRESS; -import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_NETMASK; -import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP6_ADDRESS; - -import android.net.LinkAddress; - -import com.android.internal.net.ipsec.ike.message.IkeConfigPayload; -import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttribute; -import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Address; -import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Netmask; -import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv6Address; - -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; - -/** ChildSessionConfiguration represents the negotiated configuration for a Child Session. */ -public final class ChildSessionConfiguration { - private static final int IPv4_DEFAULT_PREFIX_LEN = 32; - - private final List<IkeTrafficSelector> mInboundTs; - private final List<IkeTrafficSelector> mOutboundTs; - private final List<LinkAddress> mInternalAddressList; - - /** - * Construct an instance of {@link ChildSessionConfiguration}. - * - * <p>It is only supported to build a {@link ChildSessionConfiguration} with a Configure(Reply) - * Payload. - */ - public ChildSessionConfiguration( - List<IkeTrafficSelector> inTs, - List<IkeTrafficSelector> outTs, - IkeConfigPayload configPayload) { - this(inTs, outTs); - - if (configPayload.configType != IkeConfigPayload.CONFIG_TYPE_REPLY) { - throw new IllegalArgumentException( - "Cannot build ChildSessionConfiguration with configuration type: " - + configPayload.configType); - } - - // It is validated in IkeConfigPayload that a config reply only has at most one non-empty - // netmask and netmask exists only when IPv4 internal address exists. - ConfigAttributeIpv4Netmask netmaskAttr = null; - for (ConfigAttribute att : configPayload.recognizedAttributeList) { - if (att.attributeType == CONFIG_ATTR_INTERNAL_IP4_NETMASK && !att.isEmptyValue()) { - netmaskAttr = (ConfigAttributeIpv4Netmask) att; - } - } - - for (ConfigAttribute att : configPayload.recognizedAttributeList) { - if (att.isEmptyValue()) continue; - switch (att.attributeType) { - case CONFIG_ATTR_INTERNAL_IP4_ADDRESS: - ConfigAttributeIpv4Address addressAttr = (ConfigAttributeIpv4Address) att; - if (netmaskAttr != null) { - mInternalAddressList.add( - new LinkAddress(addressAttr.address, netmaskAttr.getPrefixLen())); - } else { - mInternalAddressList.add( - new LinkAddress(addressAttr.address, IPv4_DEFAULT_PREFIX_LEN)); - } - break; - case CONFIG_ATTR_INTERNAL_IP4_NETMASK: - // No action. - break; - case CONFIG_ATTR_INTERNAL_IP6_ADDRESS: - mInternalAddressList.add(((ConfigAttributeIpv6Address) att).linkAddress); - break; - default: - // TODO: Support DNS,Subnet and Dhcp4 attributes - } - } - } - - /** Construct an instance of {@link ChildSessionConfiguration}. */ - public ChildSessionConfiguration( - List<IkeTrafficSelector> inTs, List<IkeTrafficSelector> outTs) { - mInboundTs = Collections.unmodifiableList(inTs); - mOutboundTs = Collections.unmodifiableList(outTs); - mInternalAddressList = new LinkedList<>(); - } - - /** - * Returns the negotiated inbound traffic selectors. - * - * @return the inbound traffic selector. - */ - public List<IkeTrafficSelector> getInboundTrafficSelectors() { - return mInboundTs; - } - - /** - * Returns the negotiated outbound traffic selectors. - * - * @return the outbound traffic selector. - */ - public List<IkeTrafficSelector> getOutboundTrafficSelectors() { - return mOutboundTs; - } - - /** - * Returns the assigned internal addresses. - * - * @return assigned internal addresses, or empty list when no addresses are assigned by the - * remote IKE server. - */ - public List<LinkAddress> getInternalAddressList() { - return mInternalAddressList; - } -} diff --git a/src/java/android/net/ipsec/ike/ChildSessionOptions.java b/src/java/android/net/ipsec/ike/ChildSessionOptions.java deleted file mode 100644 index 90a30053..00000000 --- a/src/java/android/net/ipsec/ike/ChildSessionOptions.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.ipsec.ike; - -import libcore.net.InetAddressUtils; - -import java.net.InetAddress; -import java.util.LinkedList; -import java.util.List; - -/** - * This abstract class is the superclass of all classes representing a set of user configurations - * for Child Session negotiation. - */ -public abstract class ChildSessionOptions { - private static final IkeTrafficSelector DEFAULT_TRAFFIC_SELECTOR_IPV4; - // TODO: b/130765172 Add TRAFFIC_SELECTOR_IPV6 and instantiate it. - - static { - DEFAULT_TRAFFIC_SELECTOR_IPV4 = - buildDefaultTrafficSelector( - IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE); - } - - private final IkeTrafficSelector[] mLocalTrafficSelectors; - private final IkeTrafficSelector[] mRemoteTrafficSelectors; - private final ChildSaProposal[] mSaProposals; - private final boolean mIsTransport; - - protected ChildSessionOptions( - IkeTrafficSelector[] localTs, - IkeTrafficSelector[] remoteTs, - ChildSaProposal[] proposals, - boolean isTransport) { - mLocalTrafficSelectors = localTs; - mRemoteTrafficSelectors = remoteTs; - mSaProposals = proposals; - mIsTransport = isTransport; - } - - public IkeTrafficSelector[] getLocalTrafficSelectors() { - return mLocalTrafficSelectors; - } - - public IkeTrafficSelector[] getRemoteTrafficSelectors() { - return mRemoteTrafficSelectors; - } - - public ChildSaProposal[] getSaProposals() { - return mSaProposals; - } - - public boolean isTransportMode() { - return mIsTransport; - } - - /** This class represents common information for Child Sesison Options Builders. */ - protected abstract static class Builder { - protected final List<IkeTrafficSelector> mLocalTsList = new LinkedList<>(); - protected final List<IkeTrafficSelector> mRemoteTsList = new LinkedList<>(); - protected final List<SaProposal> mSaProposalList = new LinkedList<>(); - - protected Builder() { - // Currently IKE library only accepts setting up Child SA that all ports and all - // addresses are allowed on both sides. The protected traffic range is determined by the - // socket or interface that the {@link IpSecTransform} is applied to. - // TODO: b/130756765 Validate the current TS negotiation strategy. - mLocalTsList.add(DEFAULT_TRAFFIC_SELECTOR_IPV4); - mRemoteTsList.add(DEFAULT_TRAFFIC_SELECTOR_IPV4); - // TODO: add IPv6 TS to ChildSessionOptions. - } - - protected void validateAndAddSaProposal(ChildSaProposal proposal) { - mSaProposalList.add(proposal); - } - - protected void validateOrThrow() { - if (mSaProposalList.isEmpty()) { - throw new IllegalArgumentException( - "ChildSessionOptions requires at least one Child SA proposal."); - } - } - } - - private static IkeTrafficSelector buildDefaultTrafficSelector( - @IkeTrafficSelector.TrafficSelectorType int tsType) { - int startPort = IkeTrafficSelector.PORT_NUMBER_MIN; - int endPort = IkeTrafficSelector.PORT_NUMBER_MAX; - InetAddress startAddress = null; - InetAddress endAddress = null; - switch (tsType) { - case IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE: - startAddress = InetAddressUtils.parseNumericAddress("0.0.0.0"); - endAddress = InetAddressUtils.parseNumericAddress("255.255.255.255"); - break; - case IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV6_ADDR_RANGE: - // TODO: Support it. - throw new UnsupportedOperationException("Do not support IPv6."); - default: - throw new IllegalArgumentException("Invalid Traffic Selector type: " + tsType); - } - - return new IkeTrafficSelector(tsType, startPort, endPort, startAddress, endAddress); - } -} diff --git a/src/java/android/net/ipsec/ike/IkeFqdnIdentification.java b/src/java/android/net/ipsec/ike/IkeFqdnIdentification.java deleted file mode 100644 index 393a0723..00000000 --- a/src/java/android/net/ipsec/ike/IkeFqdnIdentification.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.ipsec.ike; - -import android.annotation.NonNull; - -import java.nio.charset.Charset; -import java.util.Objects; - -/** IkeFqdnIdentification represents ID information using a fully-qualified domain name (FQDN) */ -public class IkeFqdnIdentification extends IkeIdentification { - private static final Charset ASCII = Charset.forName("US-ASCII"); - - public final String fqdn; - - /** - * Construct an instance of IkeFqdnIdentification from a decoded inbound packet. - * - * <p>All characters in the FQDN are ASCII. - * - * @param fqdnBytes FQDN in byte array. - */ - public IkeFqdnIdentification(byte[] fqdnBytes) { - super(ID_TYPE_FQDN); - fqdn = new String(fqdnBytes, ASCII); - } - - /** - * Construct an instance of IkeFqdnIdentification with user provided fully-qualified domain name - * (FQDN) for building outbound packet. - * - * <p>FQDN will be formatted as US-ASCII. - * - * @param fqdn user provided fully-qualified domain name (FQDN) - */ - public IkeFqdnIdentification(@NonNull String fqdn) { - super(ID_TYPE_FQDN); - this.fqdn = fqdn; - } - - @Override - public int hashCode() { - return Objects.hash(idType, fqdn); - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof IkeFqdnIdentification)) return false; - - return fqdn.equals(((IkeFqdnIdentification) o).fqdn); - } - - /** - * Retrieve the byte-representation of the FQDN. - * - * @return the byte-representation of the FQDN. - */ - @Override - public byte[] getEncodedIdData() { - return fqdn.getBytes(ASCII); - } -} diff --git a/src/java/android/net/ipsec/ike/IkeIdentification.java b/src/java/android/net/ipsec/ike/IkeIdentification.java deleted file mode 100644 index 737df826..00000000 --- a/src/java/android/net/ipsec/ike/IkeIdentification.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.ipsec.ike; - -import android.annotation.IntDef; -import android.util.ArraySet; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.Set; - -/** - * IkeIdentification is abstract base class that represents the common information for all types of - * IKE entity identification. - * - * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.5">RFC 7296, Internet Key Exchange - * Protocol Version 2 (IKEv2)</a> - */ -public abstract class IkeIdentification { - // Set of supported ID types. - private static final Set<Integer> SUPPORTED_ID_TYPES; - - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ID_TYPE_IPV4_ADDR, - ID_TYPE_FQDN, - ID_TYPE_RFC822_ADDR, - ID_TYPE_IPV6_ADDR, - ID_TYPE_DER_ASN1_DN, - ID_TYPE_DER_ASN1_GN, - ID_TYPE_KEY_ID - }) - public @interface IdType {} - - public static final int ID_TYPE_IPV4_ADDR = 1; - public static final int ID_TYPE_FQDN = 2; - public static final int ID_TYPE_RFC822_ADDR = 3; - public static final int ID_TYPE_IPV6_ADDR = 5; - public static final int ID_TYPE_DER_ASN1_DN = 9; - public static final int ID_TYPE_DER_ASN1_GN = 10; - public static final int ID_TYPE_KEY_ID = 11; - - static { - SUPPORTED_ID_TYPES = new ArraySet(); - SUPPORTED_ID_TYPES.add(ID_TYPE_IPV4_ADDR); - SUPPORTED_ID_TYPES.add(ID_TYPE_FQDN); - SUPPORTED_ID_TYPES.add(ID_TYPE_RFC822_ADDR); - SUPPORTED_ID_TYPES.add(ID_TYPE_IPV6_ADDR); - SUPPORTED_ID_TYPES.add(ID_TYPE_DER_ASN1_DN); - SUPPORTED_ID_TYPES.add(ID_TYPE_DER_ASN1_GN); - SUPPORTED_ID_TYPES.add(ID_TYPE_KEY_ID); - } - - public final int idType; - - protected IkeIdentification(@IdType int type) { - idType = type; - } - - /** - * Return the encoded identification data in a byte array. - * - * @return the encoded identification data. - */ - public abstract byte[] getEncodedIdData(); -} diff --git a/src/java/android/net/ipsec/ike/IkeIpv4AddrIdentification.java b/src/java/android/net/ipsec/ike/IkeIpv4AddrIdentification.java deleted file mode 100644 index 350187ed..00000000 --- a/src/java/android/net/ipsec/ike/IkeIpv4AddrIdentification.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.ipsec.ike; - -import android.annotation.NonNull; - -import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException; - -import java.net.Inet4Address; -import java.net.UnknownHostException; -import java.util.Objects; - -/** IkeIpv4AddrIdentification represents ID information in IPv4 address ID type. */ -public final class IkeIpv4AddrIdentification extends IkeIdentification { - public final Inet4Address ipv4Address; - - /** - * Construct an instance of IkeIpv4AddrIdentification from a decoded inbound packet. - * - * @param ipv4AddrBytes IPv4 address in byte array. - * @throws AuthenticationFailedException for decoding bytes error. - */ - public IkeIpv4AddrIdentification(byte[] ipv4AddrBytes) throws AuthenticationFailedException { - super(ID_TYPE_IPV4_ADDR); - try { - ipv4Address = (Inet4Address) (Inet4Address.getByAddress(ipv4AddrBytes)); - } catch (ClassCastException | UnknownHostException e) { - throw new AuthenticationFailedException(e); - } - } - - /** - * Construct an instance of IkeIpv4AddrIdentification with user provided IPv4 address for - * building outbound packet. - * - * @param address user provided IPv4 address - */ - public IkeIpv4AddrIdentification(@NonNull Inet4Address address) { - super(ID_TYPE_IPV4_ADDR); - ipv4Address = address; - } - - @Override - public int hashCode() { - return Objects.hash(idType, ipv4Address); - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof IkeIpv4AddrIdentification)) return false; - - return ipv4Address.equals(((IkeIpv4AddrIdentification) o).ipv4Address); - } - - /** - * Retrieve the byte-representation of the IPv4 address. - * - * @return the byte-representation of the IPv4 address. - */ - @Override - public byte[] getEncodedIdData() { - return ipv4Address.getAddress(); - } -} diff --git a/src/java/android/net/ipsec/ike/IkeIpv6AddrIdentification.java b/src/java/android/net/ipsec/ike/IkeIpv6AddrIdentification.java deleted file mode 100644 index dfc7d5e3..00000000 --- a/src/java/android/net/ipsec/ike/IkeIpv6AddrIdentification.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.ipsec.ike; - -import android.annotation.NonNull; - -import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException; - -import java.net.Inet6Address; -import java.net.UnknownHostException; -import java.util.Objects; - -/** IkeIpv6AddrIdentification represents ID information in IPv6 address ID type. */ -public class IkeIpv6AddrIdentification extends IkeIdentification { - public final Inet6Address ipv6Address; - - /** - * Construct an instance of IkeIpv6AddrIdentification from a decoded inbound packet. - * - * @param ipv6AddrBytes IPv6 address in byte array. - * @throws AuthenticationFailedException for decoding bytes error. - */ - public IkeIpv6AddrIdentification(byte[] ipv6AddrBytes) throws AuthenticationFailedException { - super(ID_TYPE_IPV6_ADDR); - try { - ipv6Address = (Inet6Address) (Inet6Address.getByAddress(ipv6AddrBytes)); - } catch (ClassCastException | UnknownHostException e) { - throw new AuthenticationFailedException(e); - } - } - - /** - * Construct an instance of IkeIpv6AddrIdentification with user provided IPv6 address for - * building outbound packet. - * - * @param address user provided IPv6 address - */ - public IkeIpv6AddrIdentification(@NonNull Inet6Address address) { - super(ID_TYPE_IPV6_ADDR); - ipv6Address = address; - } - - @Override - public int hashCode() { - return Objects.hash(idType, ipv6Address); - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof IkeIpv6AddrIdentification)) return false; - - return ipv6Address.equals(((IkeIpv6AddrIdentification) o).ipv6Address); - } - - /** - * Retrieve the byte-representation of the IPv6 address. - * - * @return the byte-representation of the IPv6 address. - */ - @Override - public byte[] getEncodedIdData() { - return ipv6Address.getAddress(); - } -} diff --git a/src/java/android/net/ipsec/ike/IkeKeyIdIdentification.java b/src/java/android/net/ipsec/ike/IkeKeyIdIdentification.java deleted file mode 100644 index c229b9da..00000000 --- a/src/java/android/net/ipsec/ike/IkeKeyIdIdentification.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.ipsec.ike; - -import android.annotation.NonNull; - -import java.util.Objects; - -/** - * This class represents IKE ID information in Key ID type. - * - * <p>This is an octet stream that may be used to pass vendor-specific information necessary to do - * certain proprietary types of identification. - */ -public final class IkeKeyIdIdentification extends IkeIdentification { - public final byte[] keyId; - - /** - * Construct an instance of IkeKeyIdIdentification with provided Key ID - * - * @param keyId Key ID in bytes - */ - public IkeKeyIdIdentification(@NonNull byte[] keyId) { - super(ID_TYPE_KEY_ID); - this.keyId = keyId; - } - - @Override - public int hashCode() { - return Objects.hash(idType, keyId); - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof IkeKeyIdIdentification)) return false; - - return keyId.equals(((IkeKeyIdIdentification) o).keyId); - } - - /** - * Retrieve the byte-representation of the FQDN. - * - * @return the byte-representation of the FQDN. - */ - @Override - public byte[] getEncodedIdData() { - return keyId; - } -} diff --git a/src/java/android/net/ipsec/ike/IkeManager.java b/src/java/android/net/ipsec/ike/IkeManager.java deleted file mode 100644 index ef8b893b..00000000 --- a/src/java/android/net/ipsec/ike/IkeManager.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.net.ipsec.ike; - -import android.content.Context; - -import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.net.utils.Log; - -import java.util.concurrent.Executor; - -/** This class contains methods for managing IKE sessions. */ -public final class IkeManager { - private static final String IKE_TAG = "IKE"; - private static final boolean LOG_SENSITIVE = false; - - private static Log sIkeLog = new Log(IKE_TAG, LOG_SENSITIVE); - - private final Context mContext; - - /** - * Construct an instance of {@link IkeManager} - * - * @param context the application context. - */ - public IkeManager(Context context) { - mContext = context; - } - - /** - * Construct an instance of {@link IkeSession} and start the IKE Session setup process. - * - * <p>This method will immediately return a management object {@link IkeSession} and - * asynchronously initiate the IKE Session setup process. Users will be notified of the IKE - * Session and Child Session negotiation results on the callback arguments. - * - * @param ikeSessionOptions the {@link IkeSessionOptions} that contains acceptable IKE Session - * configurations. - * @param firstChildSessionOptions the {@link ChildSessionOptions} that contains acceptable - * first Child Session configurations. - * @param userCbExecutor the {@link Executor} upon which all callbacks will be posted. For - * security and consistency, the callbacks posted to this executor MUST be executed - * serially, in the order they were posted. - * @param ikeSessionCallback the {@link IkeSessionCallback} interface to notify users the state - * changes of the IKE Session. - * @param firstChildSessionCallback the {@link ChildSessionCallback} interface to notify users - * the state changes of the Child Session. - * @return an instance of {@link IkeSession} - */ - public IkeSession openIkeSession( - IkeSessionOptions ikeSessionOptions, - ChildSessionOptions firstChildSessionOptions, - Executor userCbExecutor, - IkeSessionCallback ikeSessionCallback, - ChildSessionCallback firstChildSessionCallback) { - return new IkeSession( - mContext, - ikeSessionOptions, - firstChildSessionOptions, - userCbExecutor, - ikeSessionCallback, - firstChildSessionCallback); - } - - /** Returns IKE logger. */ - public static Log getIkeLog() { - return sIkeLog; - } - - /** Injects IKE logger for testing. */ - @VisibleForTesting - public static void setIkeLog(Log log) { - sIkeLog = log; - } - - /** Resets IKE logger. */ - @VisibleForTesting - public static void resetIkeLog() { - sIkeLog = new Log(IKE_TAG, LOG_SENSITIVE); - } -} diff --git a/src/java/android/net/ipsec/ike/IkeRfc822AddrIdentification.java b/src/java/android/net/ipsec/ike/IkeRfc822AddrIdentification.java deleted file mode 100644 index 2a93bea1..00000000 --- a/src/java/android/net/ipsec/ike/IkeRfc822AddrIdentification.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.ipsec.ike; - -import android.annotation.NonNull; - -import java.nio.charset.Charset; -import java.util.Objects; - -/** This class represents IKE ID information in fully-qualified RFC 822 email address ID type. */ -public final class IkeRfc822AddrIdentification extends IkeIdentification { - private static final Charset UTF8 = Charset.forName("UTF-8"); - - public final String rfc822Name; - - /** - * Construct an instance of IkeRfc822AddrIdentification from a decoded inbound packet. - * - * <p>All characters in the RFC 822 email address are UTF-8. - * - * @param rfc822NameBytes fully-qualified RFC 822 email address in byte array. - */ - public IkeRfc822AddrIdentification(byte[] rfc822NameBytes) { - super(ID_TYPE_RFC822_ADDR); - rfc822Name = new String(rfc822NameBytes, UTF8); - } - - /** - * Construct an instance of IkeRfc822AddrIdentification with user provided fully-qualified RFC - * 822 email address for building outbound packet. - * - * <p>rfc822Name will be formatted as UTF-8. - * - * @param rfc822Name user provided fully-qualified RFC 822 email address. - */ - public IkeRfc822AddrIdentification(@NonNull String rfc822Name) { - super(ID_TYPE_RFC822_ADDR); - this.rfc822Name = rfc822Name; - } - - @Override - public int hashCode() { - return Objects.hash(idType, rfc822Name); - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof IkeRfc822AddrIdentification)) return false; - - return rfc822Name.equals(((IkeRfc822AddrIdentification) o).rfc822Name); - } - - /** - * Retrieve the byte-representation of the the RFC 822 email address. - * - * @return the byte-representation of the RFC 822 email address. - */ - @Override - public byte[] getEncodedIdData() { - return rfc822Name.getBytes(UTF8); - } -} diff --git a/src/java/android/net/ipsec/ike/IkeSaProposal.java b/src/java/android/net/ipsec/ike/IkeSaProposal.java deleted file mode 100644 index 1494f9d4..00000000 --- a/src/java/android/net/ipsec/ike/IkeSaProposal.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.ipsec.ike; - -import android.util.ArraySet; - -import com.android.internal.net.ipsec.ike.message.IkePayload; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.DhGroupTransform; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EncryptionTransform; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IntegrityTransform; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.PrfTransform; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.Transform; - -import java.util.Arrays; -import java.util.List; -import java.util.Set; - -/** - * IkeSaProposal represents a user configured set contains cryptograhic algorithms and key - * generating materials for negotiating an IKE SA. - * - * <p>User must provide at least a valid IkeSaProposal when they are creating a new IKE SA. - * - * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key Exchange - * Protocol Version 2 (IKEv2)</a> - */ -public final class IkeSaProposal extends SaProposal { - private final PrfTransform[] mPseudorandomFunctions; - - /** - * Construct an instance of IkeSaProposal. - * - * <p>This constructor is either called by IkeSaPayload for building an inbound proposal from a - * decoded packet, or called by the inner Builder to build an outbound proposal from user - * provided parameters - * - * @param encryptionAlgos encryption algorithms - * @param prfs pseudorandom functions - * @param integrityAlgos integrity algorithms - * @param dhGroups Diffie-Hellman Groups - */ - public IkeSaProposal( - EncryptionTransform[] encryptionAlgos, - PrfTransform[] prfs, - IntegrityTransform[] integrityAlgos, - DhGroupTransform[] dhGroups) { - super(IkePayload.PROTOCOL_ID_IKE, encryptionAlgos, integrityAlgos, dhGroups); - mPseudorandomFunctions = prfs; - } - - /** Gets all PRFs. */ - public PrfTransform[] getPrfTransforms() { - return mPseudorandomFunctions; - } - - @Override - public Transform[] getAllTransforms() { - List<Transform> transformList = getAllTransformsAsList(); - transformList.addAll(Arrays.asList(mPseudorandomFunctions)); - - return transformList.toArray(new Transform[transformList.size()]); - } - - @Override - public boolean isNegotiatedFrom(SaProposal reqProposal) { - return super.isNegotiatedFrom(reqProposal) - && isTransformSelectedFrom( - mPseudorandomFunctions, - ((IkeSaProposal) reqProposal).mPseudorandomFunctions); - } - - /** - * This class can be used to incrementally construct a IkeSaProposal. IkeSaProposal instances - * are immutable once built. - * - * <p>TODO: Support users to add algorithms from most preferred to least preferred. - */ - public static final class Builder extends SaProposal.Builder { - // Use set to avoid adding repeated algorithms. - private final Set<PrfTransform> mProposedPrfs = new ArraySet<>(); - - /** - * Adds an encryption algorithm with specific key length to SA proposal being built. - * - * @param algorithm encryption algorithm to add to IkeSaProposal. - * @param keyLength key length of algorithm. For algorithm that has fixed key length (e.g. - * 3DES) only KEY_LEN_UNUSED is allowed. - * @return Builder of IkeSaProposal. - * @throws IllegalArgumentException if AEAD and non-combined mode algorithms are mixed. - */ - public Builder addEncryptionAlgorithm(@EncryptionAlgorithm int algorithm, int keyLength) { - validateAndAddEncryptAlgo(algorithm, keyLength); - return this; - } - - /** - * Adds an integrity algorithm to SA proposal being built. - * - * @param algorithm integrity algorithm to add to IkeSaProposal. - * @return Builder of IkeSaProposal. - */ - public Builder addIntegrityAlgorithm(@IntegrityAlgorithm int algorithm) { - addIntegrityAlgo(algorithm); - return this; - } - - /** - * Adds a Diffie-Hellman Group to SA proposal being built. - * - * @param dhGroup to add to IkeSaProposal. - * @return Builder of IkeSaProposal. - */ - public Builder addDhGroup(@DhGroup int dhGroup) { - addDh(dhGroup); - return this; - } - - /** - * Adds a pseudorandom function to SA proposal being built. - * - * @param algorithm pseudorandom function to add to IkeSaProposal. - * @return Builder of IkeSaProposal. - */ - public Builder addPseudorandomFunction(@PseudorandomFunction int algorithm) { - // Construct PrfTransform and validate proposed algorithm during construction. - mProposedPrfs.add(new PrfTransform(algorithm)); - return this; - } - - private IntegrityTransform[] buildIntegAlgosOrThrow() { - // When building IKE SA Proposal with normal-mode ciphers, mProposedIntegrityAlgos must - // not be empty and must not have INTEGRITY_ALGORITHM_NONE. When building IKE SA - // Proposal with combined-mode ciphers, mProposedIntegrityAlgos must be either empty or - // only have INTEGRITY_ALGORITHM_NONE. - if (mProposedIntegrityAlgos.isEmpty() && !mHasAead) { - throw new IllegalArgumentException( - ERROR_TAG - + "Integrity algorithm " - + "must be proposed with normal ciphers in IKE proposal."); - } - - for (IntegrityTransform transform : mProposedIntegrityAlgos) { - if ((transform.id == INTEGRITY_ALGORITHM_NONE) != mHasAead) { - throw new IllegalArgumentException( - ERROR_TAG - + "Invalid integrity algorithm configuration" - + " for this SA Proposal"); - } - } - - return mProposedIntegrityAlgos.toArray( - new IntegrityTransform[mProposedIntegrityAlgos.size()]); - } - - private DhGroupTransform[] buildDhGroupsOrThrow() { - if (mProposedDhGroups.isEmpty()) { - throw new IllegalArgumentException( - ERROR_TAG + "DH group must be proposed in IKE SA proposal."); - } - - for (DhGroupTransform transform : mProposedDhGroups) { - if (transform.id == DH_GROUP_NONE) { - throw new IllegalArgumentException( - ERROR_TAG + "None-value DH group invalid in IKE SA proposal"); - } - } - - return mProposedDhGroups.toArray(new DhGroupTransform[mProposedDhGroups.size()]); - } - - private PrfTransform[] buildPrfsOrThrow() { - if (mProposedPrfs.isEmpty()) { - throw new IllegalArgumentException( - ERROR_TAG + "PRF must be proposed in IKE SA proposal."); - } - return mProposedPrfs.toArray(new PrfTransform[mProposedPrfs.size()]); - } - - /** - * Validates, builds and returns the IkeSaProposal - * - * @return the validated IkeSaProposal. - * @throws IllegalArgumentException if IkeSaProposal is invalid. - */ - public IkeSaProposal build() { - EncryptionTransform[] encryptionTransforms = buildEncryptAlgosOrThrow(); - PrfTransform[] prfTransforms = buildPrfsOrThrow(); - IntegrityTransform[] integrityTransforms = buildIntegAlgosOrThrow(); - DhGroupTransform[] dhGroupTransforms = buildDhGroupsOrThrow(); - - return new IkeSaProposal( - encryptionTransforms, prfTransforms, integrityTransforms, dhGroupTransforms); - } - } -} diff --git a/src/java/android/net/ipsec/ike/IkeSession.java b/src/java/android/net/ipsec/ike/IkeSession.java deleted file mode 100644 index 97fe061e..00000000 --- a/src/java/android/net/ipsec/ike/IkeSession.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.net.ipsec.ike; - -import android.content.Context; -import android.net.IpSecManager; -import android.os.HandlerThread; -import android.os.Looper; - -import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.net.ipsec.ike.IkeSessionStateMachine; - -import dalvik.system.CloseGuard; - -import java.util.concurrent.Executor; - -/** - * This class represents an IKE Session management object that allows for keying and management of - * {@link IpSecTransform}s. - * - * <p>An IKE/Child Session represents an IKE/Child SA as well as its rekeyed successors. A Child - * Session is bounded by the lifecycle of the IKE Session under which it is set up. Closing an IKE - * Session implicitly closes any remaining Child Sessions under it. - * - * <p>An IKE procedure is one or multiple IKE message exchanges that are used to create, delete or - * rekey an IKE Session or Child Session. - * - * <p>This class provides methods for user to initiate IKE procedures, such as the Creation and - * Deletion of a Child Session, or the Deletion of the IKE session. All procedures (except for IKE - * deletion) will be initiated sequentially after IKE Session is set up. - * - * @see <a href="https://tools.ietf.org/html/rfc7296">RFC 7296, Internet Key Exchange Protocol - * Version 2 (IKEv2)</a> - */ -public final class IkeSession implements AutoCloseable { - private final CloseGuard mCloseGuard = CloseGuard.get(); - - @VisibleForTesting final IkeSessionStateMachine mIkeSessionStateMachine; - - /** Package private */ - IkeSession( - Context context, - IkeSessionOptions ikeSessionOptions, - ChildSessionOptions firstChildSessionOptions, - Executor userCbExecutor, - IkeSessionCallback ikeSessionCallback, - ChildSessionCallback firstChildSessionCallback) { - this( - IkeThreadHolder.IKE_WORKER_THREAD.getLooper(), - context, - (IpSecManager) context.getSystemService(Context.IPSEC_SERVICE), - ikeSessionOptions, - firstChildSessionOptions, - userCbExecutor, - ikeSessionCallback, - firstChildSessionCallback); - } - - /** Package private */ - @VisibleForTesting - IkeSession( - Looper looper, - Context context, - IpSecManager ipSecManager, - IkeSessionOptions ikeSessionOptions, - ChildSessionOptions firstChildSessionOptions, - Executor userCbExecutor, - IkeSessionCallback ikeSessionCallback, - ChildSessionCallback firstChildSessionCallback) { - mIkeSessionStateMachine = - new IkeSessionStateMachine( - looper, - context, - ipSecManager, - ikeSessionOptions, - firstChildSessionOptions, - userCbExecutor, - ikeSessionCallback, - firstChildSessionCallback); - mIkeSessionStateMachine.openSession(); - - mCloseGuard.open("open"); - } - - @Override - public void finalize() { - if (mCloseGuard != null) { - mCloseGuard.warnIfOpen(); - } - } - - /** Initialization-on-demand holder */ - private static class IkeThreadHolder { - static final HandlerThread IKE_WORKER_THREAD; - - static { - IKE_WORKER_THREAD = new HandlerThread("IkeWorkerThread"); - IKE_WORKER_THREAD.start(); - } - } - - // TODO: b/133340675 Destroy the worker thread when there is no more alive {@link IkeSession}. - - /** - * Asynchronously request a new Child Session. - * - * <p>Users MUST provide a unique {@link ChildSessionCallback} instance for each new Child - * Session. - * - * <p>Upon setup, the {@link ChildSessionCallback#onOpened(ChildSessionConfiguration)} will be - * fired. - * - * @param childSessionOptions the {@link ChildSessionOptions} that contains the Child Session - * configurations to negotiate. - * @param childSessionCallback the {@link ChildSessionCallback} interface to notify users the - * state changes of the Child Session. - * @throws IllegalArgumentException if the ChildSessionCallback is already in use. - */ - public void openChildSession( - ChildSessionOptions childSessionOptions, ChildSessionCallback childSessionCallback) { - mIkeSessionStateMachine.openChildSession(childSessionOptions, childSessionCallback); - } - - /** - * Asynchronously delete a Child Session. - * - * <p>Upon closing, the {@link ChildSessionCallback#onClosed()} will be fired. - * - * @param childSessionCallback The {@link ChildSessionCallback} instance that uniquely identify - * the Child Session. - * @throws IllegalArgumentException if no Child Session found bound with this callback. - */ - public void closeChildSession(ChildSessionCallback childSessionCallback) { - mIkeSessionStateMachine.closeChildSession(childSessionCallback); - } - - /** - * Close the IKE session gracefully. - * - * <p>Implements {@link AutoCloseable#close()} - * - * <p>Upon closing, the {@link IkeSessionCallback#onClosed()} will be fired. - * - * <p>Closing an IKE Session implicitly closes any remaining Child Sessions negotiated under it. - * Users SHOULD stop all outbound traffic that uses these Child Sessions({@link IpSecTransform} - * pairs) before calling this method. Otherwise IPsec packets will be dropped due to the lack of - * a valid {@link IpSecTransform}. - * - * <p>Closure of an IKE session will take priority over, and cancel other procedures waiting in - * the queue (but will wait for ongoing locally initiated procedures to complete). After sending - * the Delete request, the IKE library will wait until a Delete response is received or - * retransmission timeout occurs. - */ - @Override - public void close() throws Exception { - mCloseGuard.close(); - mIkeSessionStateMachine.closeSession(); - } - - /** - * Terminate (forcibly close) the IKE session. - * - * <p>Upon closing, the {@link IkeSessionCallback#onClosed()} will be fired. - * - * <p>Closing an IKE Session implicitly closes any remaining Child Sessions negotiated under it. - * Users SHOULD stop all outbound traffic that uses these Child Sessions({@link IpSecTransform} - * pairs) before calling this method. Otherwise IPsec packets will be dropped due to the lack of - * a valid {@link IpSecTransform}. - * - * <p>Forcible closure of an IKE session will take priority over, and cancel other procedures - * waiting in the queue. It will also interrupt any ongoing locally initiated procedure. - */ - public void kill() throws Exception { - mCloseGuard.close(); - mIkeSessionStateMachine.killSession(); - } -} diff --git a/src/java/android/net/ipsec/ike/IkeSessionCallback.java b/src/java/android/net/ipsec/ike/IkeSessionCallback.java deleted file mode 100644 index c2121e2d..00000000 --- a/src/java/android/net/ipsec/ike/IkeSessionCallback.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.ipsec.ike; - -import android.annotation.NonNull; -import android.net.ipsec.ike.exceptions.IkeException; - -/** Callback interface for receiving state changes of an IKE Session. */ -public interface IkeSessionCallback { - /** - * Called when negotiation and authentication for this new IKE Session succeeds. - * - * @param sessionConfiguration the configuration information of IKE Session negotiated during - * IKE setup. - */ - void onOpened(@NonNull IkeSessionConfiguration sessionConfiguration); - - /** - * Called when either side has decided to close this Session and the deletion exchange - * finishes. - * - * <p>This method will not be fired if this deletion is caused by a fatal error. - */ - void onClosed(); - - /** - * Called if IKE Session negotiation fails or IKE Session is closed because of a fatal error. - * - * @param exception the detailed error. - */ - void onClosedExceptionally(IkeException exception); - - /** - * Called if a recoverable error is encountered in an established IKE Session. - * - * <p>A potential risk is usually detected when IKE library receives a non-protected error - * notification (e.g. INVALID_IKE_SPI) or a non-fatal error notification (e.g. - * INVALID_MESSAGE_ID). - * - * @param exception the detailed error. - */ - void onError(IkeException exception); -} diff --git a/src/java/android/net/ipsec/ike/IkeSessionConfiguration.java b/src/java/android/net/ipsec/ike/IkeSessionConfiguration.java deleted file mode 100644 index 6bbef7d0..00000000 --- a/src/java/android/net/ipsec/ike/IkeSessionConfiguration.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.ipsec.ike; - -import android.annotation.IntDef; -import android.annotation.NonNull; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** IkeSessionConfiguration represents the negotiated configuration for a IKE Session. */ -public final class IkeSessionConfiguration { - @Retention(RetentionPolicy.SOURCE) - @IntDef({EXTENSION_TYPE_FRAGMENTATION, EXTENSION_TYPE_MOBIKE}) - public @interface ExtensionType {} - - public static final int EXTENSION_TYPE_FRAGMENTATION = 1; - public static final int EXTENSION_TYPE_MOBIKE = 2; - - /** - * Gets remote(server) version information. - * - * @return application version of the remote server, or empty string if the remote server did - * not provide the application version - */ - @NonNull - public String getRemoteApplicationVersion() { - return ""; - } - - /** - * Checks if an IKE extension is enabled. - * - * <p>An IKE extension is enabled when both sides can support it. This negotiation always - * happens in IKE initial changes(IKE INIT and IKE AUTH). - * - * @param extensionType the extension type - * @return {@code true} if this extension is enabled - */ - public boolean isIkeExtensionEnabled(@ExtensionType int extensionType) { - return false; - } - - // TODO: Implement IkeSessionConfiguration. -} diff --git a/src/java/android/net/ipsec/ike/IkeSessionOptions.java b/src/java/android/net/ipsec/ike/IkeSessionOptions.java deleted file mode 100644 index 020a8888..00000000 --- a/src/java/android/net/ipsec/ike/IkeSessionOptions.java +++ /dev/null @@ -1,416 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.ipsec.ike; - -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.net.IpSecManager.UdpEncapsulationSocket; -import android.net.eap.EapSessionConfig; - -import com.android.internal.net.ipsec.ike.message.IkePayload; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.net.InetAddress; -import java.security.PrivateKey; -import java.security.cert.TrustAnchor; -import java.security.cert.X509Certificate; -import java.security.interfaces.RSAPrivateKey; -import java.util.LinkedList; -import java.util.List; - -/** - * IkeSessionOptions contains all user provided configurations for negotiating an IKE SA. - * - * <p>TODO: Make this doc more user-friendly. - */ -public final class IkeSessionOptions { - @Retention(RetentionPolicy.SOURCE) - @IntDef({IKE_AUTH_METHOD_PSK, IKE_AUTH_METHOD_PUB_KEY_SIGNATURE, IKE_AUTH_METHOD_EAP}) - public @interface IkeAuthMethod {} - - // Constants to describe user configured authentication methods. - public static final int IKE_AUTH_METHOD_PSK = 1; - public static final int IKE_AUTH_METHOD_PUB_KEY_SIGNATURE = 2; - public static final int IKE_AUTH_METHOD_EAP = 3; - - private final InetAddress mServerAddress; - private final UdpEncapsulationSocket mUdpEncapSocket; - private final IkeSaProposal[] mSaProposals; - - private final IkeIdentification mLocalIdentification; - private final IkeIdentification mRemoteIdentification; - - private final IkeAuthConfig mLocalAuthConfig; - private final IkeAuthConfig mRemoteAuthConfig; - - private final boolean mIsIkeFragmentationSupported; - - private IkeSessionOptions( - InetAddress serverAddress, - UdpEncapsulationSocket udpEncapsulationSocket, - IkeSaProposal[] proposals, - IkeIdentification localIdentification, - IkeIdentification remoteIdentification, - IkeAuthConfig localAuthConfig, - IkeAuthConfig remoteAuthConfig, - boolean isIkeFragmentationSupported) { - mServerAddress = serverAddress; - mUdpEncapSocket = udpEncapsulationSocket; - mSaProposals = proposals; - - mLocalIdentification = localIdentification; - mRemoteIdentification = remoteIdentification; - - mLocalAuthConfig = localAuthConfig; - mRemoteAuthConfig = remoteAuthConfig; - - mIsIkeFragmentationSupported = isIkeFragmentationSupported; - } - - public InetAddress getServerAddress() { - return mServerAddress; - } - - public UdpEncapsulationSocket getUdpEncapsulationSocket() { - return mUdpEncapSocket; - } - - public IkeSaProposal[] getSaProposals() { - return mSaProposals; - } - - public IkeIdentification getLocalIdentification() { - return mLocalIdentification; - } - - public IkeIdentification getRemoteIdentification() { - return mRemoteIdentification; - } - - public IkeAuthConfig getLocalAuthConfig() { - return mLocalAuthConfig; - } - - public IkeAuthConfig getRemoteAuthConfig() { - return mRemoteAuthConfig; - } - - public boolean isIkeFragmentationSupported() { - return mIsIkeFragmentationSupported; - } - /** This class contains common information of an IKEv2 authentication configuration. */ - public abstract static class IkeAuthConfig { - @IkeAuthMethod public final int mAuthMethod; - - protected IkeAuthConfig(@IkeAuthMethod int authMethod) { - mAuthMethod = authMethod; - } - } - - /** - * This class represents the configuration to support IKEv2 pre-shared-key-based authentication - * of local or remote side. - */ - public static class IkeAuthPskConfig extends IkeAuthConfig { - public final byte[] mPsk; - - private IkeAuthPskConfig(byte[] psk) { - super(IKE_AUTH_METHOD_PSK); - mPsk = psk; - } - } - - /** - * This class represents the configuration to support IKEv2 public-key-signature-based - * authentication of the remote side. - */ - public static class IkeAuthDigitalSignRemoteConfig extends IkeAuthConfig { - public final TrustAnchor mTrustAnchor; - - private IkeAuthDigitalSignRemoteConfig(TrustAnchor trustAnchor) { - super(IKE_AUTH_METHOD_PUB_KEY_SIGNATURE); - mTrustAnchor = trustAnchor; - } - } - - /** - * This class represents the configuration to support IKEv2 public-key-signature-based - * authentication of the local side. - */ - public static class IkeAuthDigitalSignLocalConfig extends IkeAuthConfig { - public final X509Certificate mEndCert; - public final List<X509Certificate> mIntermediateCerts; - public final PrivateKey mPrivateKey; - - private IkeAuthDigitalSignLocalConfig( - X509Certificate clientEndCert, - List<X509Certificate> clientIntermediateCerts, - PrivateKey privateKey) { - super(IKE_AUTH_METHOD_PUB_KEY_SIGNATURE); - mEndCert = clientEndCert; - mIntermediateCerts = clientIntermediateCerts; - mPrivateKey = privateKey; - } - } - - /** - * This class represents the configuration to support EAP authentication of the local side. - * - * <p>EAP MUST be used with IKEv2 public-key-based authentication of the responder to the - * initiator. Currently IKE library does not support the IKEv2 protocol extension(RFC 5998) - * which allows EAP methods that provide mutual authentication and key agreement to be used to - * provide extensible responder authentication for IKEv2 based on methods other than public key - * signatures. - * - * @see <a href="https://tools.ietf.org/html/rfc5998">RFC 5998, An Extension for EAP-Only - * Authentication in IKEv2</a> - */ - public static class IkeAuthEapConfig extends IkeAuthConfig { - public final EapSessionConfig mEapConfig; - - private IkeAuthEapConfig(EapSessionConfig eapConfig) { - super(IKE_AUTH_METHOD_EAP); - - mEapConfig = eapConfig; - } - } - - /** This class can be used to incrementally construct a IkeSessionOptions. */ - public static final class Builder { - private final List<IkeSaProposal> mSaProposalList = new LinkedList<>(); - - private InetAddress mServerAddress; - private UdpEncapsulationSocket mUdpEncapSocket; - - private IkeIdentification mLocalIdentification; - private IkeIdentification mRemoteIdentification; - - private IkeAuthConfig mLocalAuthConfig; - private IkeAuthConfig mRemoteAuthConfig; - - private boolean mIsIkeFragmentationSupported = false; - - /** - * Sets server address - * - * @param serverAddress IP address of remote IKE server. - * @return Builder this, to facilitate chaining. - */ - public Builder setServerAddress(@NonNull InetAddress serverAddress) { - mServerAddress = serverAddress; - return this; - } - - /** - * Sets UDP-Encapsulated socket - * - * @param udpEncapsulationSocket {@link IpSecManager.UdpEncapsulationSocket} for sending and - * receiving IKE message. - * @return Builder this, to facilitate chaining. - */ - public Builder setUdpEncapsulationSocket( - @NonNull UdpEncapsulationSocket udpEncapsulationSocket) { - mUdpEncapSocket = udpEncapsulationSocket; - return this; - } - - /** - * Sets local IKE identification. - * - * @param identification the local IKE identification. - * @return Builder this, to facilitate chaining. - */ - public Builder setLocalIdentification(IkeIdentification identification) { - mLocalIdentification = identification; - return this; - } - - /** - * Sets remote IKE identification. - * - * @param identification the remote IKE identification. - * @return Builder this, to facilitate chaining. - */ - public Builder setRemoteIdentification(IkeIdentification identification) { - mRemoteIdentification = identification; - return this; - } - - /** - * Adds an IKE SA proposal to IkeSessionOptions being built. - * - * @param proposal IKE SA proposal. - * @return Builder this, to facilitate chaining. - * @throws IllegalArgumentException if input proposal is not IKE SA proposal. - */ - public Builder addSaProposal(IkeSaProposal proposal) { - if (proposal.getProtocolId() != IkePayload.PROTOCOL_ID_IKE) { - throw new IllegalArgumentException( - "Expected IKE SA Proposal but received Child SA proposal"); - } - mSaProposalList.add(proposal); - return this; - } - - /** - * Uses pre-shared key to do IKE authentication. - * - * <p>Both client and server MUST be authenticated using the provided shared key. IKE - * authentication will fail if the remote peer tries to use other authentication methods. - * - * <p>Users MUST declare only one authentication method. Calling this function will override - * the previously set authentication configuration. - * - * @param sharedKey the shared key. - * @return Builder this, to facilitate chaining. - */ - public Builder setAuthPsk(@NonNull byte[] sharedKey) { - mLocalAuthConfig = new IkeAuthPskConfig(sharedKey); - mRemoteAuthConfig = new IkeAuthPskConfig(sharedKey); - return this; - } - - /** - * Uses EAP to do IKE authentication. - * - * <p>EAP are typically used to authenticate the IKE client to the server. It MUST be used - * in conjunction with a public-key-signature-based authentication of the server to the - * client. - * - * <p>Users MUST declare only one authentication method. Calling this function will override - * the previously set authentication configuration. - * - * @see <a href="https://tools.ietf.org/html/rfc5280">RFC 5280, Internet X.509 Public Key - * Infrastructure Certificate and Certificate Revocation List (CRL) Profile</a> - * @param serverCaCert the CA certificate for validating the received server certificate(s). - * @return Builder this, to facilitate chaining. - */ - public Builder setAuthEap( - @NonNull X509Certificate serverCaCert, @NonNull EapSessionConfig eapConfig) { - mLocalAuthConfig = new IkeAuthEapConfig(eapConfig); - - // The name constraints extension, defined in RFC 5280, indicates a name space within - // which all subject names in subsequent certificates in a certification path MUST be - // located. - mRemoteAuthConfig = - new IkeAuthDigitalSignRemoteConfig( - new TrustAnchor(serverCaCert, null /*nameConstraints*/)); - - // TODO: Investigate if we need to support the name constraints extension. - - return this; - } - - /** - * Uses certificate and digital signature to do IKE authentication. - * - * <p>The public key included by the client end certificate and the signature private key - * MUST come from the same key pair. - * - * <p>The IKE library will use the strongest signature algorithm supported by both sides. - * - * <p>Currenly only RSA digital signature is supported. - * - * @param serverCaCert the CA certificate for validating the received server certificate(s). - * @param clientEndCert the end certificate for remote server to verify the locally - * generated signature. - * @param clientPrivateKey private key to generate outbound digital signature. Only {@link - * RSAPrivateKey} is supported. - * @return Builder this, to facilitate chaining. - */ - public Builder setAuthDigitalSignature( - @NonNull X509Certificate serverCaCert, - @NonNull X509Certificate clientEndCert, - @NonNull PrivateKey clientPrivateKey) { - return setAuthDigitalSignature( - serverCaCert, - clientEndCert, - new LinkedList<X509Certificate>(), - clientPrivateKey); - } - - /** - * Uses certificate and digital signature to do IKE authentication. - * - * <p>The public key included by the client end certificate and the signature private key - * MUST come from the same key pair. - * - * <p>The IKE library will use the strongest signature algorithm supported by both sides. - * - * <p>Currenly only RSA digital signature is supported. - * - * @param serverCaCert the CA certificate for validating the received server certificate(s). - * @param clientEndCert the end certificate for remote server to verify locally generated - * signature. - * @param clientIntermediateCerts intermediate certificates for the remote server to - * validate the end certificate. - * @param clientPrivateKey private key to generate outbound digital signature. Only {@link - * RSAPrivateKey} is supported. - * @return Builder this, to facilitate chaining. - */ - public Builder setAuthDigitalSignature( - @NonNull X509Certificate serverCaCert, - @NonNull X509Certificate clientEndCert, - @NonNull List<X509Certificate> clientIntermediateCerts, - @NonNull PrivateKey clientPrivateKey) { - if (!(clientPrivateKey instanceof RSAPrivateKey)) { - throw new IllegalArgumentException("Unsupported private key type"); - } - - mLocalAuthConfig = - new IkeAuthDigitalSignLocalConfig( - clientEndCert, clientIntermediateCerts, clientPrivateKey); - mRemoteAuthConfig = - new IkeAuthDigitalSignRemoteConfig( - new TrustAnchor(serverCaCert, null /*nameConstraints*/)); - return this; - } - - /** - * Validates, builds and returns the IkeSessionOptions - * - * @return IkeSessionOptions the validated IkeSessionOptions - * @throws IllegalArgumentException if no IKE SA proposal is provided - */ - public IkeSessionOptions build() { - if (mSaProposalList.isEmpty()) { - throw new IllegalArgumentException("IKE SA proposal not found"); - } - if (mServerAddress == null - || mUdpEncapSocket == null - || mLocalIdentification == null - || mRemoteIdentification == null - || mLocalAuthConfig == null - || mRemoteAuthConfig == null) { - throw new IllegalArgumentException("Necessary parameter missing."); - } - - return new IkeSessionOptions( - mServerAddress, - mUdpEncapSocket, - mSaProposalList.toArray(new IkeSaProposal[mSaProposalList.size()]), - mLocalIdentification, - mRemoteIdentification, - mLocalAuthConfig, - mRemoteAuthConfig, - mIsIkeFragmentationSupported); - } - - // TODO: add methods for supporting IKE fragmentation. - } -} diff --git a/src/java/android/net/ipsec/ike/IkeTrafficSelector.java b/src/java/android/net/ipsec/ike/IkeTrafficSelector.java deleted file mode 100644 index 65154b9d..00000000 --- a/src/java/android/net/ipsec/ike/IkeTrafficSelector.java +++ /dev/null @@ -1,373 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.ipsec.ike; - -import android.annotation.IntDef; -import android.util.ArraySet; - -import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.nio.BufferOverflowException; -import java.nio.ByteBuffer; -import java.util.Objects; - -/** - * IkeTrafficSelector represents a Traffic Selector of a Child SA. - * - * <p>IkeTrafficSelector can be constructed by users for initiating Create Child exchange or be - * constructed from a decoded inbound Traffic Selector Payload. - * - * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.13">RFC 7296, Internet Key Exchange - * Protocol Version 2 (IKEv2)</a> - */ -public final class IkeTrafficSelector { - - // IpProtocolId consists of standard IP Protocol IDs. - @Retention(RetentionPolicy.SOURCE) - @IntDef({IP_PROTOCOL_ID_UNSPEC, IP_PROTOCOL_ID_ICMP, IP_PROTOCOL_ID_TCP, IP_PROTOCOL_ID_UDP}) - public @interface IpProtocolId {} - - // Zero value is re-defined by IKE to indicate that all IP protocols are acceptable. - @VisibleForTesting static final int IP_PROTOCOL_ID_UNSPEC = 0; - @VisibleForTesting static final int IP_PROTOCOL_ID_ICMP = 1; - @VisibleForTesting static final int IP_PROTOCOL_ID_TCP = 6; - @VisibleForTesting static final int IP_PROTOCOL_ID_UDP = 17; - - private static final ArraySet<Integer> IP_PROTOCOL_ID_SET = new ArraySet<>(); - - static { - IP_PROTOCOL_ID_SET.add(IP_PROTOCOL_ID_UNSPEC); - IP_PROTOCOL_ID_SET.add(IP_PROTOCOL_ID_ICMP); - IP_PROTOCOL_ID_SET.add(IP_PROTOCOL_ID_TCP); - IP_PROTOCOL_ID_SET.add(IP_PROTOCOL_ID_UDP); - } - - /** - * TrafficSelectorType consists of IKE standard Traffic Selector Types. - * - * @see <a - * href="https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml">Internet - * Key Exchange Version 2 (IKEv2) Parameters</a> - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE, TRAFFIC_SELECTOR_TYPE_IPV6_ADDR_RANGE}) - public @interface TrafficSelectorType {} - - public static final int TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE = 7; - public static final int TRAFFIC_SELECTOR_TYPE_IPV6_ADDR_RANGE = 8; - - public static final int PORT_NUMBER_MIN = 0; - public static final int PORT_NUMBER_MAX = 65535; - - // TODO: Consider defining these constants in a central place in Connectivity. - private static final int IPV4_ADDR_LEN = 4; - private static final int IPV6_ADDR_LEN = 16; - - @VisibleForTesting static final int TRAFFIC_SELECTOR_IPV4_LEN = 16; - @VisibleForTesting static final int TRAFFIC_SELECTOR_IPV6_LEN = 40; - - public final int tsType; - public final int ipProtocolId; - public final int selectorLength; - public final int startPort; - public final int endPort; - public final InetAddress startingAddress; - public final InetAddress endingAddress; - - private IkeTrafficSelector( - int tsType, - int ipProtocolId, - int selectorLength, - int startPort, - int endPort, - InetAddress startingAddress, - InetAddress endingAddress) { - this.tsType = tsType; - this.ipProtocolId = ipProtocolId; - this.selectorLength = selectorLength; - this.startPort = startPort; - this.endPort = endPort; - this.startingAddress = startingAddress; - this.endingAddress = endingAddress; - } - - /** - * Construct an instance of IkeTrafficSelector for building an outbound IKE message. - * - * @param tsType the Traffic Selector type. - * @param startPort the smallest port number allowed by this Traffic Selector. - * @param endPort the largest port number allowed by this Traffic Selector. - * @param startingAddress the smallest address included in this Traffic Selector. - * @param endingAddress the largest address included in this Traffic Selector. - */ - public IkeTrafficSelector( - @TrafficSelectorType int tsType, - int startPort, - int endPort, - InetAddress startingAddress, - InetAddress endingAddress) { - - this.tsType = tsType; - this.ipProtocolId = IP_PROTOCOL_ID_UNSPEC; - - switch (tsType) { - case TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE: - this.selectorLength = TRAFFIC_SELECTOR_IPV4_LEN; - - if (!(startingAddress instanceof Inet4Address) - || !(endingAddress instanceof Inet4Address)) { - throw new IllegalArgumentException( - "Invalid address range: TS_IPV4_ADDR_RANGE requires IPv4 addresses."); - } - - break; - case TRAFFIC_SELECTOR_TYPE_IPV6_ADDR_RANGE: - throw new UnsupportedOperationException("Do not support IPv6 Traffic Selector."); - // TODO: Support IPv6 Traffic Selector. - default: - throw new IllegalArgumentException("Unrecognized Traffic Selector type."); - } - - if (compareInetAddressTo(startingAddress, endingAddress) > 0) { - throw new IllegalArgumentException("Received invalid address range."); - } - - if (!isPortRangeValid(startPort, endPort)) { - throw new IllegalArgumentException( - "Invalid port range. startPort: " + startPort + " endPort: " + endPort); - } - - this.startPort = startPort; - this.endPort = endPort; - this.startingAddress = startingAddress; - this.endingAddress = endingAddress; - } - - /** - * Decode IkeTrafficSelectors from inbound Traffic Selector Payload. - * - * <p>This method is only called by IkeTsPayload when decoding inbound IKE message. - * - * @param numTs number or Traffic Selectors - * @param tsBytes encoded byte array of Traffic Selectors - * @return an array of decoded IkeTrafficSelectors - * @throws InvalidSyntaxException if received bytes are malformed. - */ - public static IkeTrafficSelector[] decodeIkeTrafficSelectors(int numTs, byte[] tsBytes) - throws InvalidSyntaxException { - IkeTrafficSelector[] tsArray = new IkeTrafficSelector[numTs]; - ByteBuffer inputBuffer = ByteBuffer.wrap(tsBytes); - - try { - for (int i = 0; i < numTs; i++) { - int tsType = Byte.toUnsignedInt(inputBuffer.get()); - switch (tsType) { - case TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE: - tsArray[i] = decodeIpv4TrafficSelector(inputBuffer); - break; - case TRAFFIC_SELECTOR_TYPE_IPV6_ADDR_RANGE: - // TODO: Support it. - throw new UnsupportedOperationException("Cannot decode this type."); - default: - throw new InvalidSyntaxException( - "Invalid Traffic Selector type: " + tsType); - } - } - } catch (BufferOverflowException e) { - // Throw exception if any Traffic Selector has invalid length. - throw new InvalidSyntaxException(e); - } - - if (inputBuffer.remaining() != 0) { - throw new InvalidSyntaxException( - "Unexpected trailing characters of Traffic Selectors."); - } - - return tsArray; - } - - // Decode Traffic Selector using IPv4 address range from a ByteBuffer. A BufferOverflowException - // will be thrown and caught by method caller if operation reaches the input ByteBuffer's limit. - private static IkeTrafficSelector decodeIpv4TrafficSelector(ByteBuffer inputBuffer) - throws InvalidSyntaxException { - // Decode and validate IP Protocol ID - int ipProtocolId = Byte.toUnsignedInt(inputBuffer.get()); - if (!IP_PROTOCOL_ID_SET.contains(ipProtocolId)) { - throw new InvalidSyntaxException("Invalid IP Protocol ID."); - } - - // Decode and validate Selector Length - int tsLength = Short.toUnsignedInt(inputBuffer.getShort()); - if (TRAFFIC_SELECTOR_IPV4_LEN != tsLength) { - throw new InvalidSyntaxException("Invalid Traffic Selector Length."); - } - - // Decode and validate ports - int startPort = Short.toUnsignedInt(inputBuffer.getShort()); - int endPort = Short.toUnsignedInt(inputBuffer.getShort()); - if (!isPortRangeValid(startPort, endPort)) { - throw new InvalidSyntaxException( - "Received invalid port range. startPort: " - + startPort - + " endPort: " - + endPort); - } - - // Decode and validate IPv4 addresses - byte[] startAddressBytes = new byte[IPV4_ADDR_LEN]; - byte[] endAddressBytes = new byte[IPV4_ADDR_LEN]; - inputBuffer.get(startAddressBytes); - inputBuffer.get(endAddressBytes); - try { - Inet4Address startAddress = - (Inet4Address) (Inet4Address.getByAddress(startAddressBytes)); - Inet4Address endAddress = (Inet4Address) (Inet4Address.getByAddress(endAddressBytes)); - - // Validate address range. - if (compareInetAddressTo(startAddress, endAddress) > 0) { - throw new InvalidSyntaxException("Received invalid IPv4 address range."); - } - - return new IkeTrafficSelector( - TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE, - ipProtocolId, - TRAFFIC_SELECTOR_IPV4_LEN, - startPort, - endPort, - startAddress, - endAddress); - } catch (ClassCastException | UnknownHostException | IllegalArgumentException e) { - throw new InvalidSyntaxException(e); - } - } - - // TODO: Add a method for decoding IPv6 traffic selector. - - // Validate port range. - private static boolean isPortRangeValid(int startPort, int endPort) { - return (startPort >= PORT_NUMBER_MIN - && startPort <= PORT_NUMBER_MAX - && endPort >= PORT_NUMBER_MIN - && endPort <= PORT_NUMBER_MAX - && startPort <= endPort); - } - - // Compare two InetAddresses. Return -1 if the first input is smaller; 1 if the second input is - // smaller; 0 if two addresses are equal. - // TODO: Consider moving it to the platform code in the future./ - private static int compareInetAddressTo(InetAddress leftAddress, InetAddress rightAddress) { - byte[] leftAddrBytes = leftAddress.getAddress(); - byte[] rightAddrBytes = rightAddress.getAddress(); - - if (leftAddrBytes.length != rightAddrBytes.length) { - throw new IllegalArgumentException("Two addresses are different types."); - } - - for (int i = 0; i < leftAddrBytes.length; i++) { - int unsignedByteLeft = Byte.toUnsignedInt(leftAddrBytes[i]); - int unsignedByteRight = Byte.toUnsignedInt(rightAddrBytes[i]); - - int result = Integer.compare(unsignedByteLeft, unsignedByteRight); - if (result != 0) return result; - } - return 0; - } - - /** - * Check if the input IkeTrafficSelector is a subset of this instance. - * - * @param ts the provided IkeTrafficSelector to check. - * @return true if the input IkeTrafficSelector is a subset of this instance, otherwise false. - */ - public boolean contains(IkeTrafficSelector ts) { - if (tsType == ts.tsType - && ipProtocolId == ts.ipProtocolId - && startPort <= ts.startPort - && endPort >= ts.endPort - && compareInetAddressTo(startingAddress, ts.startingAddress) <= 0 - && compareInetAddressTo(endingAddress, ts.endingAddress) >= 0) { - return true; - } - return false; - } - - @Override - public int hashCode() { - return Objects.hash( - tsType, - ipProtocolId, - selectorLength, - startPort, - endPort, - startingAddress, - endingAddress); - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof IkeTrafficSelector)) return false; - - IkeTrafficSelector other = (IkeTrafficSelector) o; - - if (tsType != other.tsType - || ipProtocolId != other.ipProtocolId - || startPort != other.startPort - || endPort != other.endPort) { - return false; - } - - switch (tsType) { - case TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE: - return (((Inet4Address) startingAddress) - .equals((Inet4Address) other.startingAddress) - && ((Inet4Address) endingAddress) - .equals((Inet4Address) other.endingAddress)); - case TRAFFIC_SELECTOR_TYPE_IPV6_ADDR_RANGE: - return (((Inet6Address) startingAddress) - .equals((Inet6Address) other.startingAddress) - && ((Inet6Address) endingAddress) - .equals((Inet6Address) other.endingAddress)); - default: - throw new UnsupportedOperationException("Unrecognized TS type"); - } - } - - /** - * Encode traffic selector to ByteBuffer. - * - * <p>This method will be only called by IkeTsPayload for building an outbound IKE message. - * - * @param byteBuffer destination ByteBuffer that stores encoded traffic selector. - */ - public void encodeToByteBuffer(ByteBuffer byteBuffer) { - byteBuffer - .put((byte) tsType) - .put((byte) ipProtocolId) - .putShort((short) selectorLength) - .putShort((short) startPort) - .putShort((short) endPort) - .put(startingAddress.getAddress()) - .put(endingAddress.getAddress()); - } -} diff --git a/src/java/android/net/ipsec/ike/SaProposal.java b/src/java/android/net/ipsec/ike/SaProposal.java deleted file mode 100644 index 1e0b032e..00000000 --- a/src/java/android/net/ipsec/ike/SaProposal.java +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.ipsec.ike; - -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.util.ArraySet; -import android.util.SparseArray; - -import com.android.internal.net.ipsec.ike.message.IkePayload; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.DhGroupTransform; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EncryptionTransform; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IntegrityTransform; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.PrfTransform; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.Transform; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -/** - * SaProposal represents a user configured set contains cryptograhic algorithms and key generating - * materials for negotiating an IKE or Child SA. - * - * <p>User must provide at least a valid SaProposal when they are creating a new IKE SA or Child SA. - * - * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key Exchange - * Protocol Version 2 (IKEv2)</a> - */ -public abstract class SaProposal { - - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ENCRYPTION_ALGORITHM_3DES, - ENCRYPTION_ALGORITHM_AES_CBC, - ENCRYPTION_ALGORITHM_AES_GCM_8, - ENCRYPTION_ALGORITHM_AES_GCM_12, - ENCRYPTION_ALGORITHM_AES_GCM_16 - }) - public @interface EncryptionAlgorithm {} - - public static final int ENCRYPTION_ALGORITHM_3DES = 3; - public static final int ENCRYPTION_ALGORITHM_AES_CBC = 12; - public static final int ENCRYPTION_ALGORITHM_AES_GCM_8 = 18; - public static final int ENCRYPTION_ALGORITHM_AES_GCM_12 = 19; - public static final int ENCRYPTION_ALGORITHM_AES_GCM_16 = 20; - - private static final SparseArray<String> SUPPORTED_ENCRYPTION_ALGO_TO_STR; - - static { - SUPPORTED_ENCRYPTION_ALGO_TO_STR = new SparseArray<>(); - SUPPORTED_ENCRYPTION_ALGO_TO_STR.put(ENCRYPTION_ALGORITHM_3DES, "ENCR_3DES"); - SUPPORTED_ENCRYPTION_ALGO_TO_STR.put(ENCRYPTION_ALGORITHM_AES_CBC, "ENCR_AES_CBC"); - SUPPORTED_ENCRYPTION_ALGO_TO_STR.put(ENCRYPTION_ALGORITHM_AES_GCM_8, "ENCR_AES_GCM_8"); - SUPPORTED_ENCRYPTION_ALGO_TO_STR.put(ENCRYPTION_ALGORITHM_AES_GCM_12, "ENCR_AES_GCM_12"); - SUPPORTED_ENCRYPTION_ALGO_TO_STR.put(ENCRYPTION_ALGORITHM_AES_GCM_16, "ENCR_AES_GCM_16"); - } - - public static final int KEY_LEN_UNUSED = 0; - public static final int KEY_LEN_AES_128 = 128; - public static final int KEY_LEN_AES_192 = 192; - public static final int KEY_LEN_AES_256 = 256; - - @Retention(RetentionPolicy.SOURCE) - @IntDef({PSEUDORANDOM_FUNCTION_HMAC_SHA1, PSEUDORANDOM_FUNCTION_AES128_XCBC}) - public @interface PseudorandomFunction {} - - public static final int PSEUDORANDOM_FUNCTION_HMAC_SHA1 = 2; - public static final int PSEUDORANDOM_FUNCTION_AES128_XCBC = 4; - - private static final SparseArray<String> SUPPORTED_PRF_TO_STR; - - static { - SUPPORTED_PRF_TO_STR = new SparseArray<>(); - SUPPORTED_PRF_TO_STR.put(PSEUDORANDOM_FUNCTION_HMAC_SHA1, "PRF_HMAC_SHA1"); - SUPPORTED_PRF_TO_STR.put(PSEUDORANDOM_FUNCTION_AES128_XCBC, "PRF_AES128_XCBC"); - } - - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - INTEGRITY_ALGORITHM_NONE, - INTEGRITY_ALGORITHM_HMAC_SHA1_96, - INTEGRITY_ALGORITHM_AES_XCBC_96, - INTEGRITY_ALGORITHM_HMAC_SHA2_256_128, - INTEGRITY_ALGORITHM_HMAC_SHA2_384_192, - INTEGRITY_ALGORITHM_HMAC_SHA2_512_256 - }) - public @interface IntegrityAlgorithm {} - - public static final int INTEGRITY_ALGORITHM_NONE = 0; - public static final int INTEGRITY_ALGORITHM_HMAC_SHA1_96 = 2; - public static final int INTEGRITY_ALGORITHM_AES_XCBC_96 = 5; - public static final int INTEGRITY_ALGORITHM_HMAC_SHA2_256_128 = 12; - public static final int INTEGRITY_ALGORITHM_HMAC_SHA2_384_192 = 13; - public static final int INTEGRITY_ALGORITHM_HMAC_SHA2_512_256 = 14; - - private static final SparseArray<String> SUPPORTED_INTEGRITY_ALGO_TO_STR; - - static { - SUPPORTED_INTEGRITY_ALGO_TO_STR = new SparseArray<>(); - SUPPORTED_INTEGRITY_ALGO_TO_STR.put(INTEGRITY_ALGORITHM_NONE, "AUTH_NONE"); - SUPPORTED_INTEGRITY_ALGO_TO_STR.put(INTEGRITY_ALGORITHM_HMAC_SHA1_96, "AUTH_HMAC_SHA1_96"); - SUPPORTED_INTEGRITY_ALGO_TO_STR.put(INTEGRITY_ALGORITHM_AES_XCBC_96, "AUTH_AES_XCBC_96"); - SUPPORTED_INTEGRITY_ALGO_TO_STR.put( - INTEGRITY_ALGORITHM_HMAC_SHA2_256_128, "AUTH_HMAC_SHA2_256_128"); - SUPPORTED_INTEGRITY_ALGO_TO_STR.put( - INTEGRITY_ALGORITHM_HMAC_SHA2_384_192, "AUTH_HMAC_SHA2_384_192"); - SUPPORTED_INTEGRITY_ALGO_TO_STR.put( - INTEGRITY_ALGORITHM_HMAC_SHA2_512_256, "AUTH_HMAC_SHA2_512_256"); - } - - @Retention(RetentionPolicy.SOURCE) - @IntDef({DH_GROUP_NONE, DH_GROUP_1024_BIT_MODP, DH_GROUP_2048_BIT_MODP}) - public @interface DhGroup {} - - public static final int DH_GROUP_NONE = 0; - public static final int DH_GROUP_1024_BIT_MODP = 2; - public static final int DH_GROUP_2048_BIT_MODP = 14; - - private static final SparseArray<String> SUPPORTED_DH_GROUP_TO_STR; - - static { - SUPPORTED_DH_GROUP_TO_STR = new SparseArray<>(); - SUPPORTED_DH_GROUP_TO_STR.put(DH_GROUP_NONE, "DH_NONE"); - SUPPORTED_DH_GROUP_TO_STR.put(DH_GROUP_1024_BIT_MODP, "DH_1024_BIT_MODP"); - SUPPORTED_DH_GROUP_TO_STR.put(DH_GROUP_2048_BIT_MODP, "DH_2048_BIT_MODP"); - } - - @IkePayload.ProtocolId private final int mProtocolId; - private final EncryptionTransform[] mEncryptionAlgorithms; - private final IntegrityTransform[] mIntegrityAlgorithms; - private final DhGroupTransform[] mDhGroups; - - protected SaProposal( - @IkePayload.ProtocolId int protocol, - EncryptionTransform[] encryptionAlgos, - IntegrityTransform[] integrityAlgos, - DhGroupTransform[] dhGroups) { - mProtocolId = protocol; - mEncryptionAlgorithms = encryptionAlgos; - mIntegrityAlgorithms = integrityAlgos; - mDhGroups = dhGroups; - } - - /** - * Check if the current SaProposal from the SA responder is consistent with the selected - * reqProposal from the SA initiator. - * - * @param reqProposal selected SaProposal from SA initiator - * @return if current SaProposal from SA responder is consistent with the selected reqProposal - * from SA initiator. - */ - public boolean isNegotiatedFrom(SaProposal reqProposal) { - return this.mProtocolId == reqProposal.mProtocolId - && isTransformSelectedFrom(mEncryptionAlgorithms, reqProposal.mEncryptionAlgorithms) - && isTransformSelectedFrom(mIntegrityAlgorithms, reqProposal.mIntegrityAlgorithms) - && isTransformSelectedFrom(mDhGroups, reqProposal.mDhGroups); - } - - /** Package private */ - static boolean isTransformSelectedFrom(Transform[] selected, Transform[] selectFrom) { - // If the selected proposal has multiple transforms with the same type, the responder MUST - // choose a single one. - if ((selected.length > 1) || (selected.length == 0) != (selectFrom.length == 0)) { - return false; - } - - if (selected.length == 0) return true; - - return Arrays.asList(selectFrom).contains(selected[0]); - } - - @IkePayload.ProtocolId - public int getProtocolId() { - return mProtocolId; - } - - public EncryptionTransform[] getEncryptionTransforms() { - return mEncryptionAlgorithms; - } - - public IntegrityTransform[] getIntegrityTransforms() { - return mIntegrityAlgorithms; - } - - public DhGroupTransform[] getDhGroupTransforms() { - return mDhGroups; - } - - protected List<Transform> getAllTransformsAsList() { - List<Transform> transformList = new LinkedList<>(); - - transformList.addAll(Arrays.asList(mEncryptionAlgorithms)); - transformList.addAll(Arrays.asList(mIntegrityAlgorithms)); - transformList.addAll(Arrays.asList(mDhGroups)); - - return transformList; - } - - /** - * Return all SA Transforms in this SaProposal to be encoded for building an outbound IKE - * message. - * - * <p>This method should be called by only IKE library. - * - * @return Array of Transforms to be encoded. - */ - public abstract Transform[] getAllTransforms(); - - /** This class is an abstract Builder for building a SaProposal */ - protected abstract static class Builder { - protected static final String ERROR_TAG = "Invalid SA Proposal: "; - - // Use set to avoid adding repeated algorithms. - protected final Set<EncryptionTransform> mProposedEncryptAlgos = new ArraySet<>(); - protected final Set<PrfTransform> mProposedPrfs = new ArraySet<>(); - protected final Set<IntegrityTransform> mProposedIntegrityAlgos = new ArraySet<>(); - protected final Set<DhGroupTransform> mProposedDhGroups = new ArraySet<>(); - - protected boolean mHasAead = false; - - protected static boolean isAead(@EncryptionAlgorithm int algorithm) { - switch (algorithm) { - case ENCRYPTION_ALGORITHM_3DES: - // Fall through - case ENCRYPTION_ALGORITHM_AES_CBC: - return false; - case ENCRYPTION_ALGORITHM_AES_GCM_8: - // Fall through - case ENCRYPTION_ALGORITHM_AES_GCM_12: - // Fall through - case ENCRYPTION_ALGORITHM_AES_GCM_16: - return true; - default: - // Won't hit here. - throw new IllegalArgumentException("Unsupported Encryption Algorithm."); - } - } - - protected EncryptionTransform[] buildEncryptAlgosOrThrow() { - if (mProposedEncryptAlgos.isEmpty()) { - throw new IllegalArgumentException( - ERROR_TAG + "Encryption algorithm must be proposed."); - } - - return mProposedEncryptAlgos.toArray( - new EncryptionTransform[mProposedEncryptAlgos.size()]); - } - - protected void validateAndAddEncryptAlgo( - @EncryptionAlgorithm int algorithm, int keyLength) { - // Construct EncryptionTransform and validate proposed algorithm during - // construction. - EncryptionTransform encryptionTransform = new EncryptionTransform(algorithm, keyLength); - - // Validate that only one mode encryption algorithm has been proposed. - boolean isCurrentAead = isAead(algorithm); - if (!mProposedEncryptAlgos.isEmpty() && (mHasAead ^ isCurrentAead)) { - throw new IllegalArgumentException( - ERROR_TAG - + "Proposal cannot has both normal ciphers " - + "and combined-mode ciphers."); - } - if (isCurrentAead) mHasAead = true; - - mProposedEncryptAlgos.add(encryptionTransform); - } - - protected void addIntegrityAlgo(@IntegrityAlgorithm int algorithm) { - // Construct IntegrityTransform and validate proposed algorithm during - // construction. - mProposedIntegrityAlgos.add(new IntegrityTransform(algorithm)); - } - - protected void addDh(@DhGroup int dhGroup) { - // Construct DhGroupTransform and validate proposed dhGroup during - // construction. - mProposedDhGroups.add(new DhGroupTransform(dhGroup)); - } - } - - @Override - @NonNull - public String toString() { - StringBuilder sb = new StringBuilder(); - - sb.append(IkePayload.getProtocolTypeString(mProtocolId)).append(": "); - - int len = getAllTransforms().length; - for (int i = 0; i < len; i++) { - sb.append(getAllTransforms()[i].toString()); - if (i < len - 1) sb.append("|"); - } - - return sb.toString(); - } - - /** - * Check if the provided algorithm is a supported encryption algorithm. - * - * @param algorithm IKE standard encryption algorithm id. - * @return true if the provided algorithm is a supported encryption algorithm. - */ - public static boolean isSupportedEncryptionAlgorithm(@EncryptionAlgorithm int algorithm) { - return SUPPORTED_ENCRYPTION_ALGO_TO_STR.get(algorithm) != null; - } - - /** - * Check if the provided algorithm is a supported pseudorandom function. - * - * @param algorithm IKE standard pseudorandom function id. - * @return true if the provided algorithm is a supported pseudorandom function. - */ - public static boolean isSupportedPseudorandomFunction(@PseudorandomFunction int algorithm) { - return SUPPORTED_PRF_TO_STR.get(algorithm) != null; - } - - /** - * Check if the provided algorithm is a supported integrity algorithm. - * - * @param algorithm IKE standard integrity algorithm id. - * @return true if the provided algorithm is a supported integrity algorithm. - */ - public static boolean isSupportedIntegrityAlgorithm(@IntegrityAlgorithm int algorithm) { - return SUPPORTED_INTEGRITY_ALGO_TO_STR.get(algorithm) != null; - } - - /** - * Check if the provided group number is for a supported Diffie-Hellman Group. - * - * @param dhGroup IKE standard DH Group id. - * @return true if the provided number is for a supported Diffie-Hellman Group. - */ - public static boolean isSupportedDhGroup(@DhGroup int dhGroup) { - return SUPPORTED_DH_GROUP_TO_STR.get(dhGroup) != null; - } - - /** Return the encryption algorithm as a String. */ - public static String getEncryptionAlgorithmString(int algorithm) { - if (isSupportedEncryptionAlgorithm(algorithm)) { - return SUPPORTED_ENCRYPTION_ALGO_TO_STR.get(algorithm); - } - return "ENC_Unknown_" + algorithm; - } - - /** Return the pseudorandom function as a String. */ - public static String getPseudorandomFunctionString(int algorithm) { - if (isSupportedPseudorandomFunction(algorithm)) { - return SUPPORTED_PRF_TO_STR.get(algorithm); - } - return "PRF_Unknown_" + algorithm; - } - - /** Return the integrity algorithm as a String. */ - public static String getIntegrityAlgorithmString(int algorithm) { - if (isSupportedIntegrityAlgorithm(algorithm)) { - return SUPPORTED_INTEGRITY_ALGO_TO_STR.get(algorithm); - } - return "AUTH_Unknown_" + algorithm; - } - - /** Return Diffie-Hellman Group as a String. */ - public static String getDhGroupString(int dhGroup) { - if (isSupportedDhGroup(dhGroup)) { - return SUPPORTED_DH_GROUP_TO_STR.get(dhGroup); - } - return "DH_Unknown_" + dhGroup; - } -} diff --git a/src/java/android/net/ipsec/ike/TransportModeChildSessionOptions.java b/src/java/android/net/ipsec/ike/TransportModeChildSessionOptions.java deleted file mode 100644 index 12e0601a..00000000 --- a/src/java/android/net/ipsec/ike/TransportModeChildSessionOptions.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.ipsec.ike; - -import android.annotation.NonNull; - -/** - * This class contains all user provided configuration options for negotiating a transport mode - * Child Session. - */ -public final class TransportModeChildSessionOptions extends ChildSessionOptions { - private TransportModeChildSessionOptions( - IkeTrafficSelector[] localTs, - IkeTrafficSelector[] remoteTs, - ChildSaProposal[] proposals) { - super(localTs, remoteTs, proposals, true /*isTransport*/); - } - - /** This class can be used to incrementally construct a TransportModeChildSessionOptions. */ - public static final class Builder extends ChildSessionOptions.Builder { - /** Create a Builder for negotiating a transport mode Child Session. */ - public Builder() { - super(); - } - - /** - * Adds an Child SA proposal to TransportModeChildSessionOptions being built. - * - * @param proposal Child SA proposal. - * @return Builder this, to facilitate chaining. - * @throws IllegalArgumentException if input proposal is not a Child SA proposal. - */ - public Builder addSaProposal(@NonNull ChildSaProposal proposal) { - validateAndAddSaProposal(proposal); - return this; - } - - /** - * Validates, builds and returns the TransportModeChildSessionOptions. - * - * @return the validated TransportModeChildSessionOptions. - * @throws IllegalArgumentException if no Child SA proposal is provided. - */ - public TransportModeChildSessionOptions build() { - validateOrThrow(); - - return new TransportModeChildSessionOptions( - mLocalTsList.toArray(new IkeTrafficSelector[mLocalTsList.size()]), - mRemoteTsList.toArray(new IkeTrafficSelector[mRemoteTsList.size()]), - mSaProposalList.toArray(new ChildSaProposal[mSaProposalList.size()])); - } - } -} diff --git a/src/java/android/net/ipsec/ike/TunnelModeChildSessionOptions.java b/src/java/android/net/ipsec/ike/TunnelModeChildSessionOptions.java deleted file mode 100644 index cb8268cf..00000000 --- a/src/java/android/net/ipsec/ike/TunnelModeChildSessionOptions.java +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.ipsec.ike; - -import static android.system.OsConstants.AF_INET; -import static android.system.OsConstants.AF_INET6; - -import android.annotation.NonNull; -import android.net.LinkAddress; - -import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttribute; -import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Address; -import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Dhcp; -import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Dns; -import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Netmask; -import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Subnet; -import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv6Address; -import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv6Dns; -import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv6Subnet; - -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.util.LinkedList; -import java.util.List; - -/** - * This class contains all user provided configuration options for negotiating a tunnel mode Child - * Session. - */ -public final class TunnelModeChildSessionOptions extends ChildSessionOptions { - private final ConfigAttribute[] mConfigRequests; - - private TunnelModeChildSessionOptions( - IkeTrafficSelector[] localTs, - IkeTrafficSelector[] remoteTs, - ChildSaProposal[] proposals, - ConfigAttribute[] configRequests) { - super(localTs, remoteTs, proposals, false /*isTransport*/); - mConfigRequests = configRequests; - } - - public ConfigAttribute[] getConfigurationRequests() { - return mConfigRequests; - } - - /** This class can be used to incrementally construct a TunnelModeChildSessionOptions. */ - public static final class Builder extends ChildSessionOptions.Builder { - private static final int IPv4_DEFAULT_PREFIX_LEN = 32; - - private boolean mHasIp4AddressRequest; - private List<ConfigAttribute> mConfigRequestList; - - /** Create a Builder for negotiating a transport mode Child Session. */ - public Builder() { - super(); - mHasIp4AddressRequest = false; - mConfigRequestList = new LinkedList<>(); - } - - /** - * Adds an Child SA proposal to TunnelModeChildSessionOptions being built. - * - * @param proposal Child SA proposal. - * @return Builder this, to facilitate chaining. - * @throws IllegalArgumentException if input proposal is not a Child SA proposal. - */ - public Builder addSaProposal(@NonNull ChildSaProposal proposal) { - validateAndAddSaProposal(proposal); - return this; - } - - /** - * Adds internal IP address requests to TunnelModeChildSessionOptions being built. - * - * @param addressFamily the address family. Only {@link OsConstants.AF_INET} and {@link - * OsConstants.AF_INET6} are allowed. - * @param numOfRequest the number of requests for this type of address. - * @return Builder this, to facilitate chaining. - */ - public Builder addInternalAddressRequest(int addressFamily, int numOfRequest) { - if (addressFamily == AF_INET) { - mHasIp4AddressRequest = true; - for (int i = 0; i < numOfRequest; i++) { - mConfigRequestList.add(new ConfigAttributeIpv4Address()); - } - return this; - } else if (addressFamily == AF_INET6) { - for (int i = 0; i < numOfRequest; i++) { - mConfigRequestList.add(new ConfigAttributeIpv6Address()); - } - return this; - } else { - throw new IllegalArgumentException("Invalid address family: " + addressFamily); - } - } - - /** - * Adds specific internal IP address request to TunnelModeChildSessionOptions being built. - * - * @param address the requested address. - * @param prefixLen length of the InetAddress prefix. When requesting an IPv4 address, - * prefixLen MUST be 32. - * @return Builder this, to facilitate chaining. - */ - public Builder addInternalAddressRequest(@NonNull InetAddress address, int prefixLen) { - if (address instanceof Inet4Address) { - if (prefixLen != IPv4_DEFAULT_PREFIX_LEN) { - throw new IllegalArgumentException("Invalid IPv4 prefix length: " + prefixLen); - } - mHasIp4AddressRequest = true; - mConfigRequestList.add(new ConfigAttributeIpv4Address((Inet4Address) address)); - return this; - } else if (address instanceof Inet6Address) { - mConfigRequestList.add( - new ConfigAttributeIpv6Address(new LinkAddress(address, prefixLen))); - return this; - } else { - throw new IllegalArgumentException("Invalid address " + address); - } - } - - /** - * Adds internal DNS server requests to TunnelModeChildSessionOptions being built. - * - * @param addressFamily the address family. Only {@link OsConstants.AF_INET} and {@link - * OsConstants.AF_INET6} are allowed. - * @param numOfRequest the number of requests for this type of address. - * @return Builder this, to facilitate chaining. - */ - public Builder addInternalDnsServerRequest(int addressFamily, int numOfRequest) { - if (addressFamily == AF_INET) { - for (int i = 0; i < numOfRequest; i++) { - mConfigRequestList.add(new ConfigAttributeIpv4Dns()); - } - return this; - } else if (addressFamily == AF_INET6) { - for (int i = 0; i < numOfRequest; i++) { - mConfigRequestList.add(new ConfigAttributeIpv6Dns()); - } - return this; - } else { - throw new IllegalArgumentException("Invalid address family: " + addressFamily); - } - } - - /** - * Adds internal DNS server requests to TunnelModeChildSessionOptions being built. - * - * @param address the requested DNS server address. - * @return Builder this, to facilitate chaining. - */ - public Builder addInternalDnsServerRequest(@NonNull InetAddress address) { - if (address instanceof Inet4Address) { - mConfigRequestList.add(new ConfigAttributeIpv4Dns((Inet4Address) address)); - return this; - } else if (address instanceof Inet6Address) { - mConfigRequestList.add(new ConfigAttributeIpv6Dns((Inet6Address) address)); - return this; - } else { - throw new IllegalArgumentException("Invalid address " + address); - } - } - - /** - * Adds internal subnet requests to TunnelModeChildSessionOptions being built. - * - * @param addressFamily the address family. Only {@link OsConstants.AF_INET} and {@link - * OsConstants.AF_INET6} are allowed. - * @param numOfRequest the number of requests for this type of address. - * @return Builder this, to facilitate chaining. - */ - public Builder addInternalSubnetRequest(int addressFamily, int numOfRequest) { - if (addressFamily == AF_INET) { - for (int i = 0; i < numOfRequest; i++) { - mConfigRequestList.add(new ConfigAttributeIpv4Subnet()); - } - return this; - } else if (addressFamily == AF_INET6) { - for (int i = 0; i < numOfRequest; i++) { - mConfigRequestList.add(new ConfigAttributeIpv6Subnet()); - } - return this; - } else { - throw new IllegalArgumentException("Invalid address family: " + addressFamily); - } - } - - /** - * Adds internal DHCP server requests to TunnelModeChildSessionOptions being built. - * - * <p>Only DHCP4 server requests are supported. - * - * @param addressFamily the address family. Only {@link OsConstants.AF_INET} is allowed. - * @param numOfRequest the number of requests for this type of address. - * @return Builder this, to facilitate chaining. - */ - public Builder addInternalDhcpServerRequest(int addressFamily, int numOfRequest) { - if (addressFamily == AF_INET) { - for (int i = 0; i < numOfRequest; i++) { - mConfigRequestList.add(new ConfigAttributeIpv4Dhcp()); - } - return this; - } else { - throw new IllegalArgumentException("Invalid address family: " + addressFamily); - } - } - - /** - * Adds internal DHCP server requests to TunnelModeChildSessionOptions being built. - * - * <p>Only DHCP4 server requests are supported. - * - * @param address the requested DHCP server address. - * @return Builder this, to facilitate chaining. - */ - public Builder addInternalDhcpServerRequest(@NonNull InetAddress address) { - if (address instanceof Inet4Address) { - mConfigRequestList.add(new ConfigAttributeIpv4Dhcp((Inet4Address) address)); - return this; - } else { - throw new IllegalArgumentException("Invalid address " + address); - } - } - - /** - * Validates, builds and returns the TunnelModeChildSessionOptions. - * - * @return the validated TunnelModeChildSessionOptions. - * @throws IllegalArgumentException if no Child SA proposal is provided. - */ - public TunnelModeChildSessionOptions build() { - validateOrThrow(); - - if (mHasIp4AddressRequest) { - mConfigRequestList.add(new ConfigAttributeIpv4Netmask()); - } - - return new TunnelModeChildSessionOptions( - mLocalTsList.toArray(new IkeTrafficSelector[mLocalTsList.size()]), - mRemoteTsList.toArray(new IkeTrafficSelector[mRemoteTsList.size()]), - mSaProposalList.toArray(new ChildSaProposal[mSaProposalList.size()]), - mConfigRequestList.toArray(new ConfigAttribute[mConfigRequestList.size()])); - } - } -} diff --git a/src/java/android/net/ipsec/ike/exceptions/IkeException.java b/src/java/android/net/ipsec/ike/exceptions/IkeException.java deleted file mode 100644 index 867dcf5e..00000000 --- a/src/java/android/net/ipsec/ike/exceptions/IkeException.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.net.ipsec.ike.exceptions; - -/** - * IkeException is a generic IKE library exception class that provides type safety for all the - * IKE-library-related exception classes that extend from it. - */ -public abstract class IkeException extends Exception { - protected IkeException() { - super(); - } - - protected IkeException(String message) { - super(message); - } - - protected IkeException(Throwable cause) { - super(cause); - } - - protected IkeException(String message, Throwable cause) { - super(message, cause); - } - - /** - * Returns if this exception is caused by an IKE protocol error. - * - * @return true if this exception is caused by an IKE protocol error, false otherwise. - */ - public boolean isProtocolException() { - return this instanceof IkeProtocolException; - } -} diff --git a/src/java/android/net/ipsec/ike/exceptions/IkeInternalException.java b/src/java/android/net/ipsec/ike/exceptions/IkeInternalException.java deleted file mode 100644 index 29a5af94..00000000 --- a/src/java/android/net/ipsec/ike/exceptions/IkeInternalException.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.net.ipsec.ike.exceptions; - -/** - * IkeInternalException represents all IKE-library-related exceptions that are not IKE protocol - * error. - */ -public final class IkeInternalException extends IkeException { - /** - * Constructs a new exception with the specified cause. - * - * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} - * method). - */ - public IkeInternalException(Throwable cause) { - super(cause); - } - - /** - * Constructs a new exception with the specified cause. - * - * @param message the descriptive message. - * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} - * method). - */ - public IkeInternalException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/src/java/android/net/ipsec/ike/exceptions/IkeProtocolException.java b/src/java/android/net/ipsec/ike/exceptions/IkeProtocolException.java deleted file mode 100644 index f589a267..00000000 --- a/src/java/android/net/ipsec/ike/exceptions/IkeProtocolException.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.net.ipsec.ike.exceptions; - -import android.annotation.IntDef; - -import com.android.internal.net.ipsec.ike.message.IkeNotifyPayload; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.nio.ByteBuffer; - -/** - * IkeProtocolException is an abstract class that represents the common information for all IKE - * protocol errors. - * - * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.10.1">RFC 7296, Internet Key Exchange - * Protocol Version 2 (IKEv2)</a> - */ -public abstract class IkeProtocolException extends IkeException { - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD, - ERROR_TYPE_INVALID_IKE_SPI, - ERROR_TYPE_INVALID_MAJOR_VERSION, - ERROR_TYPE_INVALID_SYNTAX, - ERROR_TYPE_INVALID_MESSAGE_ID, - ERROR_TYPE_NO_PROPOSAL_CHOSEN, - ERROR_TYPE_INVALID_KE_PAYLOAD, - ERROR_TYPE_AUTHENTICATION_FAILED, - ERROR_TYPE_SINGLE_PAIR_REQUIRED, - ERROR_TYPE_NO_ADDITIONAL_SAS, - ERROR_TYPE_INTERNAL_ADDRESS_FAILURE, - ERROR_TYPE_FAILED_CP_REQUIRED, - ERROR_TYPE_TS_UNACCEPTABLE, - ERROR_TYPE_INVALID_SELECTORS, - ERROR_TYPE_TEMPORARY_FAILURE, - ERROR_TYPE_CHILD_SA_NOT_FOUND, - }) - public @interface ErrorType {} - - public static final int ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD = 1; - public static final int ERROR_TYPE_INVALID_IKE_SPI = 4; - public static final int ERROR_TYPE_INVALID_MAJOR_VERSION = 5; - public static final int ERROR_TYPE_INVALID_SYNTAX = 7; - public static final int ERROR_TYPE_INVALID_MESSAGE_ID = 9; - public static final int ERROR_TYPE_NO_PROPOSAL_CHOSEN = 14; - public static final int ERROR_TYPE_INVALID_KE_PAYLOAD = 17; - public static final int ERROR_TYPE_AUTHENTICATION_FAILED = 24; - public static final int ERROR_TYPE_SINGLE_PAIR_REQUIRED = 34; - public static final int ERROR_TYPE_NO_ADDITIONAL_SAS = 35; - public static final int ERROR_TYPE_INTERNAL_ADDRESS_FAILURE = 36; - public static final int ERROR_TYPE_FAILED_CP_REQUIRED = 37; - public static final int ERROR_TYPE_TS_UNACCEPTABLE = 38; - public static final int ERROR_TYPE_INVALID_SELECTORS = 39; - public static final int ERROR_TYPE_TEMPORARY_FAILURE = 43; - public static final int ERROR_TYPE_CHILD_SA_NOT_FOUND = 44; - - public static final byte[] ERROR_DATA_NOT_INCLUDED = new byte[0]; - - private static final int INTEGER_BYTE_SIZE = 4; - - @ErrorType private final int mErrorType; - private final byte[] mErrorData; - - protected IkeProtocolException(@ErrorType int code) { - super(); - mErrorType = code; - mErrorData = ERROR_DATA_NOT_INCLUDED; - } - - protected IkeProtocolException(@ErrorType int code, String message) { - super(message); - mErrorType = code; - mErrorData = ERROR_DATA_NOT_INCLUDED; - } - - protected IkeProtocolException(@ErrorType int code, Throwable cause) { - super(cause); - mErrorType = code; - mErrorData = ERROR_DATA_NOT_INCLUDED; - } - - protected IkeProtocolException(@ErrorType int code, String message, Throwable cause) { - super(message, cause); - mErrorType = code; - mErrorData = ERROR_DATA_NOT_INCLUDED; - } - - // Construct an instance from a notify Payload. - protected IkeProtocolException(@ErrorType int code, byte[] notifyData) { - super(); - - if (!isValidDataLength(notifyData.length)) { - throw new IllegalArgumentException( - "Invalid error data for error type: " - + code - + " Received error data size: " - + notifyData.length); - } - - mErrorType = code; - mErrorData = notifyData; - } - - protected abstract boolean isValidDataLength(int dataLen); - - protected static byte[] integerToByteArray(int integer, int arraySize) { - if (arraySize > INTEGER_BYTE_SIZE) { - throw new IllegalArgumentException( - "Cannot convert integer to a byte array of length: " + arraySize); - } - - ByteBuffer dataBuffer = ByteBuffer.allocate(INTEGER_BYTE_SIZE); - dataBuffer.putInt(integer); - dataBuffer.rewind(); - - byte[] zeroPad = new byte[INTEGER_BYTE_SIZE - arraySize]; - byte[] byteData = new byte[arraySize]; - dataBuffer.get(zeroPad).get(byteData); - - return byteData; - } - - protected static int byteArrayToInteger(byte[] byteArray) { - if (byteArray == null || byteArray.length > INTEGER_BYTE_SIZE) { - throw new IllegalArgumentException("Cannot convert the byte array to integer"); - } - - ByteBuffer dataBuffer = ByteBuffer.allocate(INTEGER_BYTE_SIZE); - byte[] zeroPad = new byte[INTEGER_BYTE_SIZE - byteArray.length]; - dataBuffer.put(zeroPad).put(byteArray); - dataBuffer.rewind(); - - return dataBuffer.getInt(); - } - - /** - * Returns the IKE standard protocol error type of this {@link IkeProtocolException} instance. - * - * @return the IKE standard protocol error type. - */ - @ErrorType - public int getErrorType() { - return mErrorType; - } - - /** - * Returns the included error data of this {@link IkeProtocolException} instance. - * - * <p>Note that only few error types will go with an error data. This data has different meaning - * with different error types. Users should first check if an error data is included before they - * call this method. - * - * @return the included error data in byte array. - */ - public byte[] getErrorData() { - return mErrorData; - } - - /** - * Build an IKE Notification Payload for this {@link IkeProtocolException} instance. - * - * @return the notification payload. - */ - public IkeNotifyPayload buildNotifyPayload() { - return new IkeNotifyPayload(mErrorType, mErrorData); - } -} |