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