content: /*
   * Copyright (C) 2006 The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package android.net.http;
  
  import android.annotation.UnsupportedAppUsage;
  import android.os.Build;
  import java.security.cert.X509Certificate;
  
  /**
   * This class represents a set of one or more SSL errors and the associated SSL
   * certificate.
   */
  public class SslError {
  
      /**
       * Individual SSL errors (in the order from the least to the most severe):
       */
  
      /**
       * The certificate is not yet valid
       */
      public static final int SSL_NOTYETVALID = 0;
      /**
       * The certificate has expired
       */
      public static final int SSL_EXPIRED = 1;
      /**
       * Hostname mismatch
       */
      public static final int SSL_IDMISMATCH = 2;
      /**
       * The certificate authority is not trusted
       */
      public static final int SSL_UNTRUSTED = 3;
      /**
       * The date of the certificate is invalid
       */
      public static final int SSL_DATE_INVALID = 4;
      /**
       * A generic error occurred
       */
      public static final int SSL_INVALID = 5;
  
  
      /**
       * The number of different SSL errors.
       * @deprecated This constant is not necessary for using the SslError API and
       *             can change from release to release.
       */
      // Update if you add a new SSL error!!!
      @Deprecated
      public static final int SSL_MAX_ERROR = 6;
  
      /**
       * The SSL error set bitfield (each individual error is a bit index;
       * multiple individual errors can be OR-ed)
       */
      @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
      int mErrors;
  
      /**
       * The SSL certificate associated with the error set
       */
      @UnsupportedAppUsage
      final SslCertificate mCertificate;
  
      /**
       * The URL associated with the error set.
       */
      @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
      final String mUrl;
  
      /**
       * Creates a new SslError object using the supplied error and certificate.
       * The URL will be set to the empty string.
       * @param error The SSL error
       * @param certificate The associated SSL certificate
       * @deprecated Use {@link #SslError(int, SslCertificate, String)}
       */
      @Deprecated
      public SslError(int error, SslCertificate certificate) {
          this(error, certificate, "");
      }
  
      /**
       * Creates a new SslError object using the supplied error and certificate.
       * The URL will be set to the empty string.
       * @param error The SSL error
       * @param certificate The associated SSL certificate
       * @deprecated Use {@link #SslError(int, X509Certificate, String)}
       */
      @Deprecated
      public SslError(int error, X509Certificate certificate) {
          this(error, certificate, "");
      }
  
      /**
       * Creates a new SslError object using the supplied error, certificate and
       * URL.
       * @param error The SSL error
       * @param certificate The associated SSL certificate
       * @param url The associated URL
       */
      public SslError(int error, SslCertificate certificate, String url) {
          assert certificate != null;
          assert url != null;
          addError(error);
          mCertificate = certificate;
          mUrl = url;
      }
  
      /**
       * Creates a new SslError object using the supplied error, certificate and
       * URL.
       * @param error The SSL error
       * @param certificate The associated SSL certificate
       * @param url The associated URL
       */
      public SslError(int error, X509Certificate certificate, String url) {
          this(error, new SslCertificate(certificate), url);
      }
  
      /**
       * Creates an SslError object from a chromium error code.
       * @param error The chromium error code
       * @param certificate The associated SSL certificate
       * @param url The associated URL.
       * @hide  chromium error codes only available inside the framework
       */
      public static SslError SslErrorFromChromiumErrorCode(
              int error, SslCertificate cert, String url) {
          // The chromium error codes are in:
          // external/chromium/net/base/net_error_list.h
          assert (error >= -299 && error <= -200);
          if (error == -200)
              return new SslError(SSL_IDMISMATCH, cert, url);
          if (error == -201)
              return new SslError(SSL_DATE_INVALID, cert, url);
          if (error == -202)
              return new SslError(SSL_UNTRUSTED, cert, url);
          // Map all other codes to SSL_INVALID.
          return new SslError(SSL_INVALID, cert, url);
      }
  
      /**
       * Gets the SSL certificate associated with this object.
       * @return The SSL certificate, non-null.
       */
      public SslCertificate getCertificate() {
          return mCertificate;
      }
  
      /**
       * Gets the URL associated with this object.
       * @return The URL, non-null.
       */
      public String getUrl() {
          return mUrl;
      }
  
      /**
       * Adds the supplied SSL error to the set.
       * @param error The SSL error to add
       * @return True if the error being added is a known SSL error, otherwise
       *         false.
       */
      public boolean addError(int error) {
          boolean rval = (0 <= error && error < SslError.SSL_MAX_ERROR);
          if (rval) {
              mErrors |= (0x1 << error);
          }
  
          return rval;
      }
  
      /**
       * Determines whether this object includes the supplied error.
       * @param error The SSL error to check for
       * @return True if this object includes the error, otherwise false.
       */
      public boolean hasError(int error) {
          boolean rval = (0 <= error && error < SslError.SSL_MAX_ERROR);
          if (rval) {
              rval = ((mErrors & (0x1 << error)) != 0);
          }
  
          return rval;
      }
  
      /**
       * Gets the most severe SSL error in this object's set of errors.
       * Returns -1 if the set is empty.
       * @return The most severe SSL error, or -1 if the set is empty.
       */
      public int getPrimaryError() {
          if (mErrors != 0) {
              // go from the most to the least severe errors
              for (int error = SslError.SSL_MAX_ERROR - 1; error >= 0; --error) {
                  if ((mErrors & (0x1 << error)) != 0) {
                      return error;
                  }
              }
              // mErrors should never be set to an invalid value.
              assert false;
          }
  
          return -1;
      }
  
      /**
       * Returns a string representation of this object.
       * @return A String representation of this object.
       */
      public String toString() {
          return "primary error: " + getPrimaryError() +
                  " certificate: " + getCertificate() +
                  " on URL: " + getUrl();
      }
  }
  