1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package android.net.ipsec.ike; 17 18 import android.annotation.NonNull; 19 import android.net.ipsec.ike.exceptions.AuthenticationFailedException; 20 import android.os.PersistableBundle; 21 22 import com.android.server.vcn.util.PersistableBundleUtils; 23 24 import java.security.cert.X509Certificate; 25 import java.util.Objects; 26 27 import javax.security.auth.x500.X500Principal; 28 29 /** 30 * This class represents an IKE entity ID based on a DER encoded ASN.1 X.500 Distinguished Name. 31 * 32 * <p>An example might be "CN=ike.test.android.net, O=Android, C=US". 33 */ 34 public final class IkeDerAsn1DnIdentification extends IkeIdentification { 35 private static final String DER_ASN1_DN_KEY = "derAsn1Dn"; 36 /** The ASN.1 X.500 Distinguished Name */ 37 @NonNull public final X500Principal derAsn1Dn; 38 39 /** 40 * Construct an instance of IkeDerAsn1DnIdentification from a decoded inbound packet. 41 * 42 * @param derAsn1Dn the ASN.1 X.500 Distinguished Name that has been DER encoded. 43 * @hide 44 */ IkeDerAsn1DnIdentification(byte[] derAsn1DnBytes)45 public IkeDerAsn1DnIdentification(byte[] derAsn1DnBytes) throws AuthenticationFailedException { 46 super(ID_TYPE_DER_ASN1_DN); 47 48 Objects.requireNonNull(derAsn1DnBytes, "derAsn1DnBytes not provided"); 49 50 try { 51 derAsn1Dn = new X500Principal(derAsn1DnBytes); 52 } catch (IllegalArgumentException e) { 53 // Incorrect form for DN 54 throw new AuthenticationFailedException(e); 55 } 56 } 57 58 /** 59 * Construct an instance of IkeDerAsn1DnIdentification with an ASN.1 X.500 Distinguished Name 60 * 61 * @param derAsn1Dn the ASN.1 X.500 Distinguished Name. 62 */ IkeDerAsn1DnIdentification(@onNull X500Principal derAsn1Dn)63 public IkeDerAsn1DnIdentification(@NonNull X500Principal derAsn1Dn) { 64 super(ID_TYPE_DER_ASN1_DN); 65 66 Objects.requireNonNull(derAsn1Dn, "derAsn1Dn not provided"); 67 this.derAsn1Dn = derAsn1Dn; 68 } 69 70 /** 71 * Constructs this object by deserializing a PersistableBundle 72 * 73 * @hide 74 */ 75 @NonNull fromPersistableBundle(@onNull PersistableBundle in)76 public static IkeDerAsn1DnIdentification fromPersistableBundle(@NonNull PersistableBundle in) { 77 Objects.requireNonNull(in, "PersistableBundle is null"); 78 79 PersistableBundle dnBundle = in.getPersistableBundle(DER_ASN1_DN_KEY); 80 Objects.requireNonNull(dnBundle, "ASN1 DN bundle is null"); 81 82 return new IkeDerAsn1DnIdentification( 83 new X500Principal(PersistableBundleUtils.toByteArray(dnBundle))); 84 } 85 /** 86 * Serializes this object to a PersistableBundle 87 * 88 * @hide 89 */ 90 @Override 91 @NonNull toPersistableBundle()92 public PersistableBundle toPersistableBundle() { 93 final PersistableBundle result = super.toPersistableBundle(); 94 result.putPersistableBundle( 95 DER_ASN1_DN_KEY, PersistableBundleUtils.fromByteArray(derAsn1Dn.getEncoded())); 96 return result; 97 } 98 99 /** @hide */ 100 @Override hashCode()101 public int hashCode() { 102 // idType is also hashed to prevent collisions with other IkeAuthentication subtypes 103 return Objects.hash(idType, derAsn1Dn); 104 } 105 106 /** @hide */ 107 @Override equals(Object o)108 public boolean equals(Object o) { 109 if (!(o instanceof IkeDerAsn1DnIdentification)) return false; 110 111 // idType already verified based on class type; no need to check again. 112 return derAsn1Dn.equals(((IkeDerAsn1DnIdentification) o).derAsn1Dn); 113 } 114 115 /** @hide */ 116 @Override getIdTypeString()117 public String getIdTypeString() { 118 return "DER ASN.1 DN"; 119 } 120 121 /** @hide */ 122 @Override validateEndCertIdOrThrow(X509Certificate endCert)123 public void validateEndCertIdOrThrow(X509Certificate endCert) 124 throws AuthenticationFailedException { 125 if (!derAsn1Dn.equals(endCert.getSubjectX500Principal())) { 126 throw new AuthenticationFailedException( 127 "End cert subject DN and DER ASN1 DN ID mismtached"); 128 } 129 } 130 131 /** 132 * Retrieve the byte-representation of the ASN.1 X.500 DN. 133 * 134 * @return the byte-representation of the ASN.1 X.500 DN. 135 * @hide 136 */ 137 @Override getEncodedIdData()138 public byte[] getEncodedIdData() { 139 return derAsn1Dn.getEncoded(); 140 } 141 } 142