1 /*
2  * Copyright (C) 2006 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.http;
18 
19 import android.compat.annotation.UnsupportedAppUsage;
20 import android.os.Build;
21 
22 import java.security.cert.X509Certificate;
23 
24 /**
25  * This class represents a set of one or more SSL errors and the associated SSL
26  * certificate.
27  */
28 public class SslError {
29 
30     /**
31      * Individual SSL errors (in the order from the least to the most severe):
32      */
33 
34     /**
35      * The certificate is not yet valid
36      */
37     public static final int SSL_NOTYETVALID = 0;
38     /**
39      * The certificate has expired
40      */
41     public static final int SSL_EXPIRED = 1;
42     /**
43      * Hostname mismatch
44      */
45     public static final int SSL_IDMISMATCH = 2;
46     /**
47      * The certificate authority is not trusted
48      */
49     public static final int SSL_UNTRUSTED = 3;
50     /**
51      * The date of the certificate is invalid
52      */
53     public static final int SSL_DATE_INVALID = 4;
54     /**
55      * A generic error occurred
56      */
57     public static final int SSL_INVALID = 5;
58 
59 
60     /**
61      * The number of different SSL errors.
62      * @deprecated This constant is not necessary for using the SslError API and
63      *             can change from release to release.
64      */
65     // Update if you add a new SSL error!!!
66     @Deprecated
67     public static final int SSL_MAX_ERROR = 6;
68 
69     /**
70      * The SSL error set bitfield (each individual error is a bit index;
71      * multiple individual errors can be OR-ed)
72      */
73     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
74     int mErrors;
75 
76     /**
77      * The SSL certificate associated with the error set
78      */
79     @UnsupportedAppUsage
80     final SslCertificate mCertificate;
81 
82     /**
83      * The URL associated with the error set.
84      */
85     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
86     final String mUrl;
87 
88     /**
89      * Creates a new SslError object using the supplied error and certificate.
90      * The URL will be set to the empty string.
91      * @param error The SSL error
92      * @param certificate The associated SSL certificate
93      * @deprecated Use {@link #SslError(int, SslCertificate, String)}
94      */
95     @Deprecated
SslError(int error, SslCertificate certificate)96     public SslError(int error, SslCertificate certificate) {
97         this(error, certificate, "");
98     }
99 
100     /**
101      * Creates a new SslError object using the supplied error and certificate.
102      * The URL will be set to the empty string.
103      * @param error The SSL error
104      * @param certificate The associated SSL certificate
105      * @deprecated Use {@link #SslError(int, X509Certificate, String)}
106      */
107     @Deprecated
SslError(int error, X509Certificate certificate)108     public SslError(int error, X509Certificate certificate) {
109         this(error, certificate, "");
110     }
111 
112     /**
113      * Creates a new SslError object using the supplied error, certificate and
114      * URL.
115      * @param error The SSL error
116      * @param certificate The associated SSL certificate
117      * @param url The associated URL
118      */
SslError(int error, SslCertificate certificate, String url)119     public SslError(int error, SslCertificate certificate, String url) {
120         assert certificate != null;
121         assert url != null;
122         addError(error);
123         mCertificate = certificate;
124         mUrl = url;
125     }
126 
127     /**
128      * Creates a new SslError object using the supplied error, certificate and
129      * URL.
130      * @param error The SSL error
131      * @param certificate The associated SSL certificate
132      * @param url The associated URL
133      */
SslError(int error, X509Certificate certificate, String url)134     public SslError(int error, X509Certificate certificate, String url) {
135         this(error, new SslCertificate(certificate), url);
136     }
137 
138     /**
139      * Creates an SslError object from a chromium error code.
140      * @param error The chromium error code
141      * @param certificate The associated SSL certificate
142      * @param url The associated URL.
143      * @hide  chromium error codes only available inside the framework
144      */
SslErrorFromChromiumErrorCode( int error, SslCertificate cert, String url)145     public static SslError SslErrorFromChromiumErrorCode(
146             int error, SslCertificate cert, String url) {
147         // The chromium error codes are in:
148         // external/chromium/net/base/net_error_list.h
149         assert (error >= -299 && error <= -200);
150         if (error == -200)
151             return new SslError(SSL_IDMISMATCH, cert, url);
152         if (error == -201)
153             return new SslError(SSL_DATE_INVALID, cert, url);
154         if (error == -202)
155             return new SslError(SSL_UNTRUSTED, cert, url);
156         // Map all other codes to SSL_INVALID.
157         return new SslError(SSL_INVALID, cert, url);
158     }
159 
160     /**
161      * Gets the SSL certificate associated with this object.
162      * @return The SSL certificate, non-null.
163      */
getCertificate()164     public SslCertificate getCertificate() {
165         return mCertificate;
166     }
167 
168     /**
169      * Gets the URL associated with this object.
170      * @return The URL, non-null.
171      */
getUrl()172     public String getUrl() {
173         return mUrl;
174     }
175 
176     /**
177      * Adds the supplied SSL error to the set.
178      * @param error The SSL error to add
179      * @return True if the error being added is a known SSL error, otherwise
180      *         false.
181      */
addError(int error)182     public boolean addError(int error) {
183         boolean rval = (0 <= error && error < SslError.SSL_MAX_ERROR);
184         if (rval) {
185             mErrors |= (0x1 << error);
186         }
187 
188         return rval;
189     }
190 
191     /**
192      * Determines whether this object includes the supplied error.
193      * @param error The SSL error to check for
194      * @return True if this object includes the error, otherwise false.
195      */
hasError(int error)196     public boolean hasError(int error) {
197         boolean rval = (0 <= error && error < SslError.SSL_MAX_ERROR);
198         if (rval) {
199             rval = ((mErrors & (0x1 << error)) != 0);
200         }
201 
202         return rval;
203     }
204 
205     /**
206      * Gets the most severe SSL error in this object's set of errors.
207      * Returns -1 if the set is empty.
208      * @return The most severe SSL error, or -1 if the set is empty.
209      */
getPrimaryError()210     public int getPrimaryError() {
211         if (mErrors != 0) {
212             // go from the most to the least severe errors
213             for (int error = SslError.SSL_MAX_ERROR - 1; error >= 0; --error) {
214                 if ((mErrors & (0x1 << error)) != 0) {
215                     return error;
216                 }
217             }
218             // mErrors should never be set to an invalid value.
219             assert false;
220         }
221 
222         return -1;
223     }
224 
225     /**
226      * Returns a string representation of this object.
227      * @return A String representation of this object.
228      */
toString()229     public String toString() {
230         return "primary error: " + getPrimaryError() +
231                 " certificate: " + getCertificate() +
232                 " on URL: " + getUrl();
233     }
234 }
235