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