Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 330e1089 authored by Nathan Harold's avatar Nathan Harold
Browse files

Add API Surface for creating IpSec Transforms

This CL adds an API to set up an IPSec Security Association
and Security Policy to perform Transport-Mode and Tunnel-Mode encapuslation
of IP Packets.

Bug: 30984788
Bug: 34811752
Test: 34812052, 34811227
Change-Id: Ic9f63c7bb366302a24baa3e1b79020210910ac0a
parent b987777f
Loading
Loading
Loading
Loading
+63 −0
Original line number Diff line number Diff line
@@ -8188,6 +8188,7 @@ package android.content {
    field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardware_properties";
    field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
    field public static final java.lang.String INPUT_SERVICE = "input";
    field public static final java.lang.String IPSEC_SERVICE = "ipsec";
    field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler";
    field public static final java.lang.String KEYGUARD_SERVICE = "keyguard";
    field public static final java.lang.String LAUNCHER_APPS_SERVICE = "launcherapps";
@@ -23724,6 +23725,68 @@ package android.net {
    field public static final android.os.Parcelable.Creator<android.net.IpPrefix> CREATOR;
  }
  public final class IpSecAlgorithm implements android.os.Parcelable {
    ctor public IpSecAlgorithm(java.lang.String, byte[]);
    ctor public IpSecAlgorithm(java.lang.String, byte[], int);
    method public int describeContents();
    method public byte[] getKey();
    method public java.lang.String getName();
    method public int getTruncationLengthBits();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final java.lang.String ALGO_AUTH_HMAC_MD5 = "hmac(md5)";
    field public static final java.lang.String ALGO_AUTH_HMAC_SHA1 = "hmac(sha1)";
    field public static final java.lang.String ALGO_AUTH_HMAC_SHA256 = "hmac(sha256)";
    field public static final java.lang.String ALGO_AUTH_HMAC_SHA384 = "hmac(sha384)";
    field public static final java.lang.String ALGO_AUTH_HMAC_SHA512 = "hmac(sha512)";
    field public static final java.lang.String ALGO_CRYPT_AES_CBC = "cbc(aes)";
    field public static final android.os.Parcelable.Creator<android.net.IpSecAlgorithm> CREATOR;
  }
  public final class IpSecManager {
    method public void applyTransportModeTransform(java.net.Socket, android.net.IpSecTransform) throws java.io.IOException;
    method public void applyTransportModeTransform(java.net.DatagramSocket, android.net.IpSecTransform) throws java.io.IOException;
    method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket(int) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
    method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket() throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
    method public void removeTransportModeTransform(java.net.Socket, android.net.IpSecTransform);
    method public void removeTransportModeTransform(java.net.DatagramSocket, android.net.IpSecTransform);
    method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
    field public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; // 0x0
  }
  public static final class IpSecManager.ResourceUnavailableException extends android.util.AndroidException {
  }
  public static final class IpSecManager.SecurityParameterIndex implements java.lang.AutoCloseable {
    method public void close();
    method public int getSpi();
  }
  public static final class IpSecManager.SpiUnavailableException extends android.util.AndroidException {
    method public int getSpi();
  }
  public static final class IpSecManager.UdpEncapsulationSocket implements java.lang.AutoCloseable {
    method public void close();
    method public int getPort();
    method public java.io.FileDescriptor getSocket();
  }
  public final class IpSecTransform implements java.lang.AutoCloseable {
    method public void close();
    field public static final int DIRECTION_IN = 0; // 0x0
    field public static final int DIRECTION_OUT = 1; // 0x1
  }
  public static class IpSecTransform.Builder {
    ctor public IpSecTransform.Builder(android.content.Context);
    method public android.net.IpSecTransform buildTransportModeTransform(java.net.InetAddress) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
    method public android.net.IpSecTransform.Builder setAuthentication(int, android.net.IpSecAlgorithm);
    method public android.net.IpSecTransform.Builder setEncryption(int, android.net.IpSecAlgorithm);
    method public android.net.IpSecTransform.Builder setIpv4Encapsulation(android.net.IpSecManager.UdpEncapsulationSocket, int);
    method public android.net.IpSecTransform.Builder setSpi(int, int);
    method public android.net.IpSecTransform.Builder setSpi(int, android.net.IpSecManager.SecurityParameterIndex);
  }
  public class LinkAddress implements android.os.Parcelable {
    method public int describeContents();
    method public java.net.InetAddress getAddress();
+68 −0
Original line number Diff line number Diff line
@@ -8522,6 +8522,7 @@ package android.content {
    field public static final java.lang.String HDMI_CONTROL_SERVICE = "hdmi_control";
    field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
    field public static final java.lang.String INPUT_SERVICE = "input";
    field public static final java.lang.String IPSEC_SERVICE = "ipsec";
    field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler";
    field public static final java.lang.String KEYGUARD_SERVICE = "keyguard";
    field public static final java.lang.String LAUNCHER_APPS_SERVICE = "launcherapps";
@@ -25561,6 +25562,73 @@ package android.net {
    field public static final android.os.Parcelable.Creator<android.net.IpPrefix> CREATOR;
  }
  public final class IpSecAlgorithm implements android.os.Parcelable {
    ctor public IpSecAlgorithm(java.lang.String, byte[]);
    ctor public IpSecAlgorithm(java.lang.String, byte[], int);
    method public int describeContents();
    method public byte[] getKey();
    method public java.lang.String getName();
    method public int getTruncationLengthBits();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final java.lang.String ALGO_AUTH_HMAC_MD5 = "hmac(md5)";
    field public static final java.lang.String ALGO_AUTH_HMAC_SHA1 = "hmac(sha1)";
    field public static final java.lang.String ALGO_AUTH_HMAC_SHA256 = "hmac(sha256)";
    field public static final java.lang.String ALGO_AUTH_HMAC_SHA384 = "hmac(sha384)";
    field public static final java.lang.String ALGO_AUTH_HMAC_SHA512 = "hmac(sha512)";
    field public static final java.lang.String ALGO_CRYPT_AES_CBC = "cbc(aes)";
    field public static final android.os.Parcelable.Creator<android.net.IpSecAlgorithm> CREATOR;
  }
  public final class IpSecManager {
    method public void applyTransportModeTransform(java.net.Socket, android.net.IpSecTransform) throws java.io.IOException;
    method public void applyTransportModeTransform(java.net.DatagramSocket, android.net.IpSecTransform) throws java.io.IOException;
    method public void applyTunnelModeTransform(android.net.Network, android.net.IpSecTransform);
    method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket(int) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
    method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket() throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
    method public void removeTransportModeTransform(java.net.Socket, android.net.IpSecTransform);
    method public void removeTransportModeTransform(java.net.DatagramSocket, android.net.IpSecTransform);
    method public void removeTunnelModeTransform(android.net.Network, android.net.IpSecTransform);
    method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
    field public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; // 0x0
  }
  public static final class IpSecManager.ResourceUnavailableException extends android.util.AndroidException {
  }
  public static final class IpSecManager.SecurityParameterIndex implements java.lang.AutoCloseable {
    method public void close();
    method public int getSpi();
  }
  public static final class IpSecManager.SpiUnavailableException extends android.util.AndroidException {
    method public int getSpi();
  }
  public static final class IpSecManager.UdpEncapsulationSocket implements java.lang.AutoCloseable {
    method public void close();
    method public int getPort();
    method public java.io.FileDescriptor getSocket();
  }
  public final class IpSecTransform implements java.lang.AutoCloseable {
    method public void close();
    field public static final int DIRECTION_IN = 0; // 0x0
    field public static final int DIRECTION_OUT = 1; // 0x1
  }
  public static class IpSecTransform.Builder {
    ctor public IpSecTransform.Builder(android.content.Context);
    method public android.net.IpSecTransform buildTransportModeTransform(java.net.InetAddress) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
    method public android.net.IpSecTransform buildTunnelModeTransform(java.net.InetAddress, java.net.InetAddress);
    method public android.net.IpSecTransform.Builder setAuthentication(int, android.net.IpSecAlgorithm);
    method public android.net.IpSecTransform.Builder setEncryption(int, android.net.IpSecAlgorithm);
    method public android.net.IpSecTransform.Builder setIpv4Encapsulation(android.net.IpSecManager.UdpEncapsulationSocket, int);
    method public android.net.IpSecTransform.Builder setNattKeepalive(int);
    method public android.net.IpSecTransform.Builder setSpi(int, int);
    method public android.net.IpSecTransform.Builder setSpi(int, android.net.IpSecManager.SecurityParameterIndex);
    method public android.net.IpSecTransform.Builder setUnderlyingNetwork(android.net.Network);
  }
  public class LinkAddress implements android.os.Parcelable {
    method public int describeContents();
    method public java.net.InetAddress getAddress();
+63 −0
Original line number Diff line number Diff line
@@ -8199,6 +8199,7 @@ package android.content {
    field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardware_properties";
    field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
    field public static final java.lang.String INPUT_SERVICE = "input";
    field public static final java.lang.String IPSEC_SERVICE = "ipsec";
    field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler";
    field public static final java.lang.String KEYGUARD_SERVICE = "keyguard";
    field public static final java.lang.String LAUNCHER_APPS_SERVICE = "launcherapps";
@@ -23797,6 +23798,68 @@ package android.net {
    field public static final android.os.Parcelable.Creator<android.net.IpPrefix> CREATOR;
  }
  public final class IpSecAlgorithm implements android.os.Parcelable {
    ctor public IpSecAlgorithm(java.lang.String, byte[]);
    ctor public IpSecAlgorithm(java.lang.String, byte[], int);
    method public int describeContents();
    method public byte[] getKey();
    method public java.lang.String getName();
    method public int getTruncationLengthBits();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final java.lang.String ALGO_AUTH_HMAC_MD5 = "hmac(md5)";
    field public static final java.lang.String ALGO_AUTH_HMAC_SHA1 = "hmac(sha1)";
    field public static final java.lang.String ALGO_AUTH_HMAC_SHA256 = "hmac(sha256)";
    field public static final java.lang.String ALGO_AUTH_HMAC_SHA384 = "hmac(sha384)";
    field public static final java.lang.String ALGO_AUTH_HMAC_SHA512 = "hmac(sha512)";
    field public static final java.lang.String ALGO_CRYPT_AES_CBC = "cbc(aes)";
    field public static final android.os.Parcelable.Creator<android.net.IpSecAlgorithm> CREATOR;
  }
  public final class IpSecManager {
    method public void applyTransportModeTransform(java.net.Socket, android.net.IpSecTransform) throws java.io.IOException;
    method public void applyTransportModeTransform(java.net.DatagramSocket, android.net.IpSecTransform) throws java.io.IOException;
    method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket(int) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
    method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket() throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
    method public void removeTransportModeTransform(java.net.Socket, android.net.IpSecTransform);
    method public void removeTransportModeTransform(java.net.DatagramSocket, android.net.IpSecTransform);
    method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
    field public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; // 0x0
  }
  public static final class IpSecManager.ResourceUnavailableException extends android.util.AndroidException {
  }
  public static final class IpSecManager.SecurityParameterIndex implements java.lang.AutoCloseable {
    method public void close();
    method public int getSpi();
  }
  public static final class IpSecManager.SpiUnavailableException extends android.util.AndroidException {
    method public int getSpi();
  }
  public static final class IpSecManager.UdpEncapsulationSocket implements java.lang.AutoCloseable {
    method public void close();
    method public int getPort();
    method public java.io.FileDescriptor getSocket();
  }
  public final class IpSecTransform implements java.lang.AutoCloseable {
    method public void close();
    field public static final int DIRECTION_IN = 0; // 0x0
    field public static final int DIRECTION_OUT = 1; // 0x1
  }
  public static class IpSecTransform.Builder {
    ctor public IpSecTransform.Builder(android.content.Context);
    method public android.net.IpSecTransform buildTransportModeTransform(java.net.InetAddress) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
    method public android.net.IpSecTransform.Builder setAuthentication(int, android.net.IpSecAlgorithm);
    method public android.net.IpSecTransform.Builder setEncryption(int, android.net.IpSecAlgorithm);
    method public android.net.IpSecTransform.Builder setIpv4Encapsulation(android.net.IpSecManager.UdpEncapsulationSocket, int);
    method public android.net.IpSecTransform.Builder setSpi(int, int);
    method public android.net.IpSecTransform.Builder setSpi(int, android.net.IpSecManager.SecurityParameterIndex);
  }
  public class LinkAddress implements android.os.Parcelable {
    method public int describeContents();
    method public java.net.InetAddress getAddress();
+13 −0
Original line number Diff line number Diff line
@@ -2662,6 +2662,7 @@ public abstract class Context {
            VIBRATOR_SERVICE,
            //@hide: STATUS_BAR_SERVICE,
            CONNECTIVITY_SERVICE,
            IPSEC_SERVICE,
            //@hide: UPDATE_LOCK_SERVICE,
            //@hide: NETWORKMANAGEMENT_SERVICE,
            NETWORK_STATS_SERVICE,
@@ -2763,6 +2764,9 @@ public abstract class Context {
     *  <dt> {@link #CONNECTIVITY_SERVICE} ("connection")
     *  <dd> A {@link android.net.ConnectivityManager ConnectivityManager} for
     *  handling management of network connections.
     *  <dt> {@link #IPSEC_SERVICE} ("ipsec")
     *  <dd> A {@link android.net.IpSecManager IpSecManager} for managing IPSec on
     *  sockets and networks.
     *  <dt> {@link #WIFI_SERVICE} ("wifi")
     *  <dd> A {@link android.net.wifi.WifiManager WifiManager} for management of Wi-Fi
     *  connectivity.  On releases before NYC, it should only be obtained from an application
@@ -3092,6 +3096,15 @@ public abstract class Context {
     */
    public static final String CONNECTIVITY_SERVICE = "connectivity";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.net.IpSecManager} for encrypting Sockets or Networks with
     * IPSec.
     *
     * @see #getSystemService
     */
    public static final String IPSEC_SERVICE = "ipsec";

    /**
     * Use with {@link #getSystemService} to retrieve a {@link
     * android.os.IUpdateLock} for managing runtime sequences that
+181 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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;

import android.annotation.StringDef;
import android.os.Parcel;
import android.os.Parcelable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * IpSecAlgorithm specifies a single algorithm that can be applied to an IpSec Transform. Refer to
 * RFC 4301.
 */
public final class IpSecAlgorithm implements Parcelable {

    /**
     * AES-CBC Encryption/Ciphering Algorithm.
     *
     * <p>Valid lengths for this key are {128, 192, 256}.
     */
    public static final String ALGO_CRYPT_AES_CBC = "cbc(aes)";

    /**
     * MD5 HMAC Authentication/Integrity Algorithm. This algorithm is not recommended for use in new
     * applications and is provided for legacy compatibility with 3gpp infrastructure.
     *
     * <p>Valid truncation lengths are multiples of 8 bits from 96 to (default) 128.
     */
    public static final String ALGO_AUTH_HMAC_MD5 = "hmac(md5)";

    /**
     * SHA1 HMAC Authentication/Integrity Algorithm. This algorithm is not recommended for use in
     * new applications and is provided for legacy compatibility with 3gpp infrastructure.
     *
     * <p>Valid truncation lengths are multiples of 8 bits from 96 to (default) 160.
     */
    public static final String ALGO_AUTH_HMAC_SHA1 = "hmac(sha1)";

    /**
     * SHA256 HMAC Authentication/Integrity Algorithm.
     *
     * <p>Valid truncation lengths are multiples of 8 bits from 96 to (default) 256.
     */
    public static final String ALGO_AUTH_HMAC_SHA256 = "hmac(sha256)";

    /**
     * SHA384 HMAC Authentication/Integrity Algorithm.
     *
     * <p>Valid truncation lengths are multiples of 8 bits from 192 to (default) 384.
     */
    public static final String ALGO_AUTH_HMAC_SHA384 = "hmac(sha384)";
    /**
     * SHA512 HMAC Authentication/Integrity Algorithm
     *
     * <p>Valid truncation lengths are multiples of 8 bits from 256 to (default) 512.
     */
    public static final String ALGO_AUTH_HMAC_SHA512 = "hmac(sha512)";

    /** @hide */
    @StringDef({
        ALGO_CRYPT_AES_CBC,
        ALGO_AUTH_HMAC_MD5,
        ALGO_AUTH_HMAC_SHA1,
        ALGO_AUTH_HMAC_SHA256,
        ALGO_AUTH_HMAC_SHA512
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface AlgorithmName {}

    private final String mName;
    private final byte[] mKey;
    private final int mTruncLenBits;

    /**
     * Specify a IpSecAlgorithm of one of the supported types including the truncation length of the
     * algorithm
     *
     * @param algorithm type for IpSec.
     * @param key non-null Key padded to a multiple of 8 bits.
     */
    public IpSecAlgorithm(String algorithm, byte[] key) {
        this(algorithm, key, key.length * 8);
    }

    /**
     * Specify a IpSecAlgorithm of one of the supported types including the truncation length of the
     * algorithm
     *
     * @param algoName precise name of the algorithm to be used.
     * @param key non-null Key padded to a multiple of 8 bits.
     * @param truncLenBits the number of bits of output hash to use; only meaningful for
     *     Authentication.
     */
    public IpSecAlgorithm(@AlgorithmName String algoName, byte[] key, int truncLenBits) {
        if (!isTruncationLengthValid(algoName, truncLenBits)) {
            throw new IllegalArgumentException("Unknown algorithm or invalid length");
        }
        mName = algoName;
        mKey = key.clone();
        mTruncLenBits = Math.min(truncLenBits, key.length * 8);
    }

    /** Retrieve the algorithm name */
    public String getName() {
        return mName;
    }

    /** Retrieve the key for this algorithm */
    public byte[] getKey() {
        return mKey.clone();
    }

    /**
     * Retrieve the truncation length, in bits, for the key in this algo. By default this will be
     * the length in bits of the key.
     */
    public int getTruncationLengthBits() {
        return mTruncLenBits;
    }

    /* Parcelable Implementation */
    public int describeContents() {
        return 0;
    }

    /** Write to parcel */
    public void writeToParcel(Parcel out, int flags) {
        out.writeString(mName);
        out.writeByteArray(mKey);
        out.writeInt(mTruncLenBits);
    }

    /** Parcelable Creator */
    public static final Parcelable.Creator<IpSecAlgorithm> CREATOR =
            new Parcelable.Creator<IpSecAlgorithm>() {
                public IpSecAlgorithm createFromParcel(Parcel in) {
                    return new IpSecAlgorithm(in);
                }

                public IpSecAlgorithm[] newArray(int size) {
                    return new IpSecAlgorithm[size];
                }
            };

    private IpSecAlgorithm(Parcel in) {
        mName = in.readString();
        mKey = in.createByteArray();
        mTruncLenBits = in.readInt();
    }

    private static boolean isTruncationLengthValid(String algo, int truncLenBits) {
        switch (algo) {
            case ALGO_AUTH_HMAC_MD5:
                return (truncLenBits >= 96 && truncLenBits <= 128);
            case ALGO_AUTH_HMAC_SHA1:
                return (truncLenBits >= 96 && truncLenBits <= 160);
            case ALGO_AUTH_HMAC_SHA256:
                return (truncLenBits >= 96 && truncLenBits <= 256);
            case ALGO_AUTH_HMAC_SHA384:
                return (truncLenBits >= 192 && truncLenBits <= 384);
            case ALGO_AUTH_HMAC_SHA512:
                return (truncLenBits >= 256 && truncLenBits <= 512);
            default:
                return false;
        }
    }
};
Loading