1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.net.vcn.persistablebundleutils; 18 19 import static com.android.internal.annotations.VisibleForTesting.Visibility; 20 21 import android.annotation.NonNull; 22 import android.net.InetAddresses; 23 import android.net.ipsec.ike.IkeDerAsn1DnIdentification; 24 import android.net.ipsec.ike.IkeFqdnIdentification; 25 import android.net.ipsec.ike.IkeIdentification; 26 import android.net.ipsec.ike.IkeIpv4AddrIdentification; 27 import android.net.ipsec.ike.IkeIpv6AddrIdentification; 28 import android.net.ipsec.ike.IkeKeyIdIdentification; 29 import android.net.ipsec.ike.IkeRfc822AddrIdentification; 30 import android.os.PersistableBundle; 31 32 import com.android.internal.annotations.VisibleForTesting; 33 import com.android.server.vcn.util.PersistableBundleUtils; 34 35 import java.net.Inet4Address; 36 import java.net.Inet6Address; 37 import java.util.Objects; 38 39 import javax.security.auth.x500.X500Principal; 40 41 /** 42 * Abstract utility class to convert IkeIdentification to/from PersistableBundle. 43 * 44 * @hide 45 */ 46 @VisibleForTesting(visibility = Visibility.PRIVATE) 47 public final class IkeIdentificationUtils { 48 private static final String ID_TYPE_KEY = "ID_TYPE_KEY"; 49 50 private static final String DER_ASN1_DN_KEY = "DER_ASN1_DN_KEY"; 51 private static final String FQDN_KEY = "FQDN_KEY"; 52 private static final String KEY_ID_KEY = "KEY_ID_KEY"; 53 private static final String IP4_ADDRESS_KEY = "IP4_ADDRESS_KEY"; 54 private static final String IP6_ADDRESS_KEY = "IP6_ADDRESS_KEY"; 55 private static final String RFC822_ADDRESS_KEY = "RFC822_ADDRESS_KEY"; 56 57 private static final int ID_TYPE_DER_ASN1_DN = 1; 58 private static final int ID_TYPE_FQDN = 2; 59 private static final int ID_TYPE_IPV4_ADDR = 3; 60 private static final int ID_TYPE_IPV6_ADDR = 4; 61 private static final int ID_TYPE_KEY_ID = 5; 62 private static final int ID_TYPE_RFC822_ADDR = 6; 63 64 /** Serializes an IkeIdentification to a PersistableBundle. */ 65 @NonNull toPersistableBundle(@onNull IkeIdentification ikeId)66 public static PersistableBundle toPersistableBundle(@NonNull IkeIdentification ikeId) { 67 if (ikeId instanceof IkeDerAsn1DnIdentification) { 68 final PersistableBundle result = createPersistableBundle(ID_TYPE_DER_ASN1_DN); 69 IkeDerAsn1DnIdentification id = (IkeDerAsn1DnIdentification) ikeId; 70 result.putPersistableBundle( 71 DER_ASN1_DN_KEY, 72 PersistableBundleUtils.fromByteArray(id.derAsn1Dn.getEncoded())); 73 return result; 74 } else if (ikeId instanceof IkeFqdnIdentification) { 75 final PersistableBundle result = createPersistableBundle(ID_TYPE_FQDN); 76 IkeFqdnIdentification id = (IkeFqdnIdentification) ikeId; 77 result.putString(FQDN_KEY, id.fqdn); 78 return result; 79 } else if (ikeId instanceof IkeIpv4AddrIdentification) { 80 final PersistableBundle result = createPersistableBundle(ID_TYPE_IPV4_ADDR); 81 IkeIpv4AddrIdentification id = (IkeIpv4AddrIdentification) ikeId; 82 result.putString(IP4_ADDRESS_KEY, id.ipv4Address.getHostAddress()); 83 return result; 84 } else if (ikeId instanceof IkeIpv6AddrIdentification) { 85 final PersistableBundle result = createPersistableBundle(ID_TYPE_IPV6_ADDR); 86 IkeIpv6AddrIdentification id = (IkeIpv6AddrIdentification) ikeId; 87 result.putString(IP6_ADDRESS_KEY, id.ipv6Address.getHostAddress()); 88 return result; 89 } else if (ikeId instanceof IkeKeyIdIdentification) { 90 final PersistableBundle result = createPersistableBundle(ID_TYPE_KEY_ID); 91 IkeKeyIdIdentification id = (IkeKeyIdIdentification) ikeId; 92 result.putPersistableBundle(KEY_ID_KEY, PersistableBundleUtils.fromByteArray(id.keyId)); 93 return result; 94 } else if (ikeId instanceof IkeRfc822AddrIdentification) { 95 final PersistableBundle result = createPersistableBundle(ID_TYPE_RFC822_ADDR); 96 IkeRfc822AddrIdentification id = (IkeRfc822AddrIdentification) ikeId; 97 result.putString(RFC822_ADDRESS_KEY, id.rfc822Name); 98 return result; 99 } else { 100 throw new IllegalStateException("Unrecognized IkeIdentification subclass"); 101 } 102 } 103 createPersistableBundle(int idType)104 private static PersistableBundle createPersistableBundle(int idType) { 105 final PersistableBundle result = new PersistableBundle(); 106 result.putInt(ID_TYPE_KEY, idType); 107 return result; 108 } 109 110 /** Constructs an IkeIdentification by deserializing a PersistableBundle. */ 111 @NonNull fromPersistableBundle(@onNull PersistableBundle in)112 public static IkeIdentification fromPersistableBundle(@NonNull PersistableBundle in) { 113 Objects.requireNonNull(in, "PersistableBundle was null"); 114 int idType = in.getInt(ID_TYPE_KEY); 115 switch (idType) { 116 case ID_TYPE_DER_ASN1_DN: 117 final PersistableBundle dnBundle = in.getPersistableBundle(DER_ASN1_DN_KEY); 118 Objects.requireNonNull(dnBundle, "ASN1 DN was null"); 119 return new IkeDerAsn1DnIdentification( 120 new X500Principal(PersistableBundleUtils.toByteArray(dnBundle))); 121 case ID_TYPE_FQDN: 122 return new IkeFqdnIdentification(in.getString(FQDN_KEY)); 123 case ID_TYPE_IPV4_ADDR: 124 final String v4AddressStr = in.getString(IP4_ADDRESS_KEY); 125 Objects.requireNonNull(v4AddressStr, "IPv4 address was null"); 126 return new IkeIpv4AddrIdentification( 127 (Inet4Address) InetAddresses.parseNumericAddress(v4AddressStr)); 128 case ID_TYPE_IPV6_ADDR: 129 final String v6AddressStr = in.getString(IP6_ADDRESS_KEY); 130 Objects.requireNonNull(v6AddressStr, "IPv6 address was null"); 131 return new IkeIpv6AddrIdentification( 132 (Inet6Address) InetAddresses.parseNumericAddress(v6AddressStr)); 133 case ID_TYPE_KEY_ID: 134 final PersistableBundle keyIdBundle = in.getPersistableBundle(KEY_ID_KEY); 135 Objects.requireNonNull(in, "Key ID was null"); 136 return new IkeKeyIdIdentification(PersistableBundleUtils.toByteArray(keyIdBundle)); 137 case ID_TYPE_RFC822_ADDR: 138 return new IkeRfc822AddrIdentification(in.getString(RFC822_ADDRESS_KEY)); 139 default: 140 throw new IllegalStateException("Unrecognized IKE ID type: " + idType); 141 } 142 } 143 } 144