1 /*
2  * Copyright (C) 2022 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.security.cts;
18 
19 import static org.junit.Assert.assertFalse;
20 import static org.junit.Assume.assumeFalse;
21 import static org.junit.Assume.assumeNotNull;
22 
23 import android.platform.test.annotations.AsbSecurityTest;
24 
25 import androidx.test.runner.AndroidJUnit4;
26 
27 import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
28 
29 import org.junit.Test;
30 import org.junit.runner.RunWith;
31 
32 import java.io.ByteArrayInputStream;
33 import java.io.InputStream;
34 import java.security.Principal;
35 import java.security.cert.Certificate;
36 import java.security.cert.CertificateEncodingException;
37 import java.security.cert.CertificateFactory;
38 import java.util.Enumeration;
39 import java.util.Hashtable;
40 import java.util.Vector;
41 
42 import javax.net.ssl.HostnameVerifier;
43 import javax.net.ssl.HttpsURLConnection;
44 import javax.net.ssl.SSLPeerUnverifiedException;
45 import javax.net.ssl.SSLSession;
46 import javax.net.ssl.SSLSessionBindingEvent;
47 import javax.net.ssl.SSLSessionBindingListener;
48 import javax.net.ssl.SSLSessionContext;
49 import javax.security.cert.CertificateException;
50 
51 // Taken reference from
52 // libcore/support/src/test/java/org/apache/harmony/xnet/tests/support/mySSLSession.java
53 
54 class CVE_2021_0341_SSLSession implements SSLSession {
55 
56     private byte[] idData;
57     private String nameHost = null;
58     private int namePort = -1;
59     private Hashtable table;
60     private boolean invalidateDone = false;
61     private Certificate[] certs = null;
62     private javax.security.cert.X509Certificate[] xCerts = null;
63 
CVE_2021_0341_SSLSession(Certificate[] xc)64     public CVE_2021_0341_SSLSession(Certificate[] xc)
65             throws CertificateEncodingException, CertificateException {
66         certs = xc;
67         xCerts = new javax.security.cert.X509Certificate[xc.length];
68         int i = 0;
69         for (Certificate cert : xc) {
70             xCerts[i++] = javax.security.cert.X509Certificate.getInstance(cert.getEncoded());
71         }
72     }
73 
getApplicationBufferSize()74     public int getApplicationBufferSize() {
75         return 1234567;
76     }
77 
getCipherSuite()78     public String getCipherSuite() {
79         return "SuiteName";
80     }
81 
getCreationTime()82     public long getCreationTime() {
83         return 1000L;
84     }
85 
getId()86     public byte[] getId() {
87         return idData;
88     }
89 
getLastAccessedTime()90     public long getLastAccessedTime() {
91         return 2000L;
92     }
93 
getLocalCertificates()94     public Certificate[] getLocalCertificates() {
95         return null;
96     }
97 
getLocalPrincipal()98     public Principal getLocalPrincipal() {
99         return null;
100     }
101 
getPacketBufferSize()102     public int getPacketBufferSize() {
103         return 12345;
104     }
105 
getPeerCertificates()106     public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
107         assumeFalse("peer not authenticated", (certs == null));
108         return certs;
109     }
110 
getPeerCertificateChain()111     public javax.security.cert.X509Certificate[] getPeerCertificateChain()
112             throws SSLPeerUnverifiedException {
113         assumeFalse("peer not authenticated", (xCerts == null));
114         return xCerts;
115     }
116 
getPeerHost()117     public String getPeerHost() {
118         return nameHost;
119     }
120 
getPeerPort()121     public int getPeerPort() {
122         return namePort;
123     }
124 
getPeerPrincipal()125     public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
126         return null;
127     }
128 
getProtocol()129     public String getProtocol() {
130         return "ProtocolName";
131     }
132 
getSessionContext()133     public SSLSessionContext getSessionContext() {
134         return null;
135     }
136 
putValue(String s, Object obj)137     public void putValue(String s, Object obj) {
138         assumeFalse("arguments can not be null", (s == null || obj == null));
139         Object obj1 = table.put(s, obj);
140         if (obj1 instanceof SSLSessionBindingListener) {
141             SSLSessionBindingEvent sslsessionbindingevent = new SSLSessionBindingEvent(this, s);
142             ((SSLSessionBindingListener) obj1).valueUnbound(sslsessionbindingevent);
143         }
144         if (obj instanceof SSLSessionBindingListener) {
145             SSLSessionBindingEvent sslsessionbindingevent1 = new SSLSessionBindingEvent(this, s);
146             ((SSLSessionBindingListener) obj).valueBound(sslsessionbindingevent1);
147         }
148     }
149 
removeValue(String s)150     public void removeValue(String s) {
151         assumeFalse("argument can not be null", (s == null));
152         Object obj = table.remove(s);
153         if (obj instanceof SSLSessionBindingListener) {
154             SSLSessionBindingEvent sslsessionbindingevent = new SSLSessionBindingEvent(this, s);
155             ((SSLSessionBindingListener) obj).valueUnbound(sslsessionbindingevent);
156         }
157     }
158 
getValue(String s)159     public Object getValue(String s) {
160         assumeFalse("argument can not be null", (s == null));
161         return table.get(s);
162     }
163 
getValueNames()164     public String[] getValueNames() {
165         Vector vector = new Vector();
166         Enumeration enumeration = table.keys();
167         while (enumeration.hasMoreElements()) {
168             vector.addElement(enumeration.nextElement());
169         }
170         String as[] = new String[vector.size()];
171         vector.copyInto(as);
172         return as;
173     }
174 
invalidate()175     public void invalidate() {
176         invalidateDone = true;
177     }
178 
isValid()179     public boolean isValid() {
180         return invalidateDone;
181     }
182 }
183 
184 
185 @RunWith(AndroidJUnit4.class)
186 public class CVE_2021_0341 extends StsExtraBusinessLogicTestCase  {
187 
188     public final static byte[] X509_TEST_CERTIFICATE = ("-----BEGIN CERTIFICATE-----\n"
189             + "MIIC3DCCAcSgAwIBAgIURJspNgSx6GVbOLijqravWoGlm+0wDQYJKoZIhvcNAQEL\n"
190             + "BQAwETEPMA0GA1UECgwGZ29vZ2xlMB4XDTIyMDIxNzExNTE1NFoXDTMxMTExNzEx\n"
191             + "NTE1NFowETEPMA0GA1UECgwGZ29vZ2xlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\n"
192             + "MIIBCgKCAQEA2PxVfeoY/uA66aVRXpuZXodTBFBGowTt/lAJxR8fVjDwRTOrRTrr\n"
193             + "2qdLPPK40lFQOSfHw/g6+9WjNjjSDBP+U2Agrvo8cU5R1DwJWyK2wcHOtBcL2bsj\n"
194             + "kRx18CZtZUu51a8KEhMCaIoHgGzwGMZkJnfmfO9ABbMfFsyn6KxFf0MXG3bRcQU7\n"
195             + "LyCXyQbo2Lal68QiTMXZs9rXN/a8ex+RmP9PKaXIEsIOeDrtLhzcWyNjrtTuDRoR\n"
196             + "K49xHOpz4EmqHLDzIKuhqyyo9tLR+okK0BRJoNxmfvRTbxNbjzpTTFgyB4KrKBCO\n"
197             + "VQXJROlBf7594xlCMn0QSwElVT4bMaMw/QIDAQABoywwKjAoBgNVHREEITAfggkq\n"
198             + "LmJhci5jb22CEiou44Kw44O844Kw44OrLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEA\n"
199             + "piIwY84InjX4BUmAmM+D9CHD/9euucGxgdXqL6kKG1HRL6lHfwZAIxhlbn3jWFEx\n"
200             + "k5DTkaL039FGLvYzMI0McwTIuHY/7JwCbZUJ3pVl0waW4sab+2LScnpe9c422Tqb\n"
201             + "hECEhc71E/kRlG9FjQN3wjEj3RcnWZAWCqAnJN/dcd/1tBD88tzHVckDC9mSvxzP\n"
202             + "hkmIRRifIDxcrmx7PkpJ6dAfiw9e1Pl5THdsPTDtiGJ4hjlsAi8ury3rrx31lsyo\n"
203             + "kAwQy23Q7Rcbr2z8bijDuSWWWc9RRsz+O/ePy35NJci/RUwVFTpvOFtahC30Jdv3\n"
204             + "vpmqxLqEF7Z9I1yb3Q6YUg==\n" + "-----END CERTIFICATE-----\n").getBytes();
205 
206     /**
207      * b/171980069
208      */
209     @AsbSecurityTest(cveBugId = 171980069)
210     @Test
testPocCVE_2021_0341()211     public void testPocCVE_2021_0341() throws Exception {
212         CertificateFactory cf = CertificateFactory.getInstance("X.509");
213         assumeNotNull(cf);
214         HostnameVerifier verifier = HttpsURLConnection.getDefaultHostnameVerifier();
215         assumeNotNull(verifier);
216         InputStream in = new ByteArrayInputStream(X509_TEST_CERTIFICATE);
217         java.security.cert.X509Certificate x509 =
218                 (java.security.cert.X509Certificate) cf.generateCertificate(in);
219         assumeNotNull(x509);
220         CVE_2021_0341_SSLSession session =
221                 new CVE_2021_0341_SSLSession(new java.security.cert.X509Certificate[] {x509});
222         assertFalse(verifier.verify("\u82b1\u5b50.bar.com", session));
223     }
224 }
225