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.annotation.SystemApi;
20 
21 import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException;
22 
23 import java.security.cert.X509Certificate;
24 import java.util.Objects;
25 
26 import javax.security.auth.x500.X500Principal;
27 
28 /**
29  * This class represents an IKE entity ID based on a DER encoded ASN.1 X.500 Distinguished Name.
30  *
31  * <p>An example might be "CN=ike.test.android.net, O=Android, C=US".
32  *
33  * @hide
34  */
35 @SystemApi
36 public final class IkeDerAsn1DnIdentification extends IkeIdentification {
37     /** The ASN.1 X.500 Distinguished Name */
38     @NonNull public final X500Principal derAsn1Dn;
39 
40     /**
41      * Construct an instance of IkeDerAsn1DnIdentification from a decoded inbound packet.
42      *
43      * @param derAsn1Dn the ASN.1 X.500 Distinguished Name that has been DER encoded.
44      * @hide
45      */
IkeDerAsn1DnIdentification(byte[] derAsn1DnBytes)46     public IkeDerAsn1DnIdentification(byte[] derAsn1DnBytes) throws AuthenticationFailedException {
47         super(ID_TYPE_DER_ASN1_DN);
48 
49         Objects.requireNonNull(derAsn1DnBytes, "derAsn1DnBytes not provided");
50 
51         try {
52             derAsn1Dn = new X500Principal(derAsn1DnBytes);
53         } catch (IllegalArgumentException e) {
54             // Incorrect form for DN
55             throw new AuthenticationFailedException(e);
56         }
57     }
58 
59     /**
60      * Construct an instance of IkeDerAsn1DnIdentification with an ASN.1 X.500 Distinguished Name
61      *
62      * @param derAsn1Dn the ASN.1 X.500 Distinguished Name.
63      */
IkeDerAsn1DnIdentification(@onNull X500Principal derAsn1Dn)64     public IkeDerAsn1DnIdentification(@NonNull X500Principal derAsn1Dn) {
65         super(ID_TYPE_DER_ASN1_DN);
66 
67         Objects.requireNonNull(derAsn1Dn, "derAsn1Dn not provided");
68         this.derAsn1Dn = derAsn1Dn;
69     }
70 
71     /** @hide */
72     @Override
hashCode()73     public int hashCode() {
74         // idType is also hashed to prevent collisions with other IkeAuthentication subtypes
75         return Objects.hash(idType, derAsn1Dn);
76     }
77 
78     /** @hide */
79     @Override
equals(Object o)80     public boolean equals(Object o) {
81         if (!(o instanceof IkeDerAsn1DnIdentification)) return false;
82 
83         // idType already verified based on class type; no need to check again.
84         return derAsn1Dn.equals(((IkeDerAsn1DnIdentification) o).derAsn1Dn);
85     }
86 
87     /** @hide */
88     @Override
getIdTypeString()89     public String getIdTypeString() {
90         return "DER ASN.1 DN";
91     }
92 
93     /** @hide */
94     @Override
validateEndCertIdOrThrow(X509Certificate endCert)95     public void validateEndCertIdOrThrow(X509Certificate endCert)
96             throws AuthenticationFailedException {
97         if (!derAsn1Dn.equals(endCert.getSubjectX500Principal())) {
98             throw new AuthenticationFailedException(
99                     "End cert subject DN and DER ASN1 DN ID mismtached");
100         }
101     }
102 
103     /**
104      * Retrieve the byte-representation of the ASN.1 X.500 DN.
105      *
106      * @return the byte-representation of the ASN.1 X.500 DN.
107      * @hide
108      */
109     @Override
getEncodedIdData()110     public byte[] getEncodedIdData() {
111         return derAsn1Dn.getEncoded();
112     }
113 }
114