Home | History | Annotate | Download | only in jca
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
      4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      5  *
      6  * This code is free software; you can redistribute it and/or modify it
      7  * under the terms of the GNU General Public License version 2 only, as
      8  * published by the Free Software Foundation.  Oracle designates this
      9  * particular file as subject to the "Classpath" exception as provided
     10  * by Oracle in the LICENSE file that accompanied this code.
     11  *
     12  * This code is distributed in the hope that it will be useful, but WITHOUT
     13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     15  * version 2 for more details (a copy is included in the LICENSE file that
     16  * accompanied this code).
     17  *
     18  * You should have received a copy of the GNU General Public License version
     19  * 2 along with this work; if not, write to the Free Software Foundation,
     20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     21  *
     22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     23  * or visit www.oracle.com if you need additional information or have any
     24  * questions.
     25  */
     26 
     27 package sun.security.jca;
     28 
     29 import dalvik.system.VMRuntime;
     30 import java.security.NoSuchAlgorithmException;
     31 import java.security.Provider;
     32 import java.util.Arrays;
     33 import java.util.HashSet;
     34 import java.util.Locale;
     35 import java.util.Set;
     36 
     37 /**
     38  * Collection of methods to get and set provider list. Also includes
     39  * special code for the provider list during JAR verification.
     40  *
     41  * @author  Andreas Sterbenz
     42  * @since   1.5
     43  */
     44 public class Providers {
     45 
     46     private static final ThreadLocal<ProviderList> threadLists =
     47         new InheritableThreadLocal<>();
     48 
     49     // number of threads currently using thread-local provider lists
     50     // tracked to allow an optimization if == 0
     51     private static volatile int threadListsUsed;
     52 
     53     // current system-wide provider list
     54     // Note volatile immutable object, so no synchronization needed.
     55     private static volatile ProviderList providerList;
     56 
     57     // Android-added: Keep reference to system-created Bouncy Castle provider
     58     // See comments near deprecation methods at the bottom of this file.
     59     private static volatile Provider SYSTEM_BOUNCY_CASTLE_PROVIDER;
     60 
     61     static {
     62         // set providerList to empty list first in case initialization somehow
     63         // triggers a getInstance() call (although that should not happen)
     64         providerList = ProviderList.EMPTY;
     65         providerList = ProviderList.fromSecurityProperties();
     66 
     67         // BEGIN Android-added: Initialize all providers and assert that this succeeds.
     68         // removeInvalid is specified to try initializing all configured providers
     69         // and removing those that aren't instantiable. This has the side effect
     70         // of eagerly initializing all providers.
     71         final int numConfiguredProviders = providerList.size();
     72         providerList = providerList.removeInvalid();
     73         if (numConfiguredProviders != providerList.size()) {
     74             throw new AssertionError("Unable to configure default providers");
     75         }
     76         // END Android-added: Initialize all providers and assert that this succeeds.
     77         // Android-added: Set BC provider instance
     78         SYSTEM_BOUNCY_CASTLE_PROVIDER = providerList.getProvider("BC");
     79     }
     80 
     81     private Providers() {
     82         // empty
     83     }
     84 
     85     // we need special handling to resolve circularities when loading
     86     // signed JAR files during startup. The code below is part of that.
     87 
     88     // Basically, before we load data from a signed JAR file, we parse
     89     // the PKCS#7 file and verify the signature. We need a
     90     // CertificateFactory, Signatures, etc. to do that. We have to make
     91     // sure that we do not try to load the implementation from the JAR
     92     // file we are just verifying.
     93     //
     94     // To avoid that, we use different provider settings during JAR
     95     // verification.  However, we do not want those provider settings to
     96     // interfere with other parts of the system. Therefore, we make them local
     97     // to the Thread executing the JAR verification code.
     98     //
     99     // The code here is used by sun.security.util.SignatureFileVerifier.
    100     // See there for details.
    101 
    102     private static final String BACKUP_PROVIDER_CLASSNAME =
    103         "sun.security.provider.VerificationProvider";
    104 
    105     // Hardcoded classnames of providers to use for JAR verification.
    106     // MUST NOT be on the bootclasspath and not in signed JAR files.
    107     private static final String[] jarVerificationProviders = {
    108         // BEGIN Android-changed: Use Conscrypt and BC, not the sun.security providers.
    109         /*
    110         "sun.security.provider.Sun",
    111         "sun.security.rsa.SunRsaSign",
    112         // Note: SunEC *is* in a signed JAR file, but it's not signed
    113         // by EC itself. So it's still safe to be listed here.
    114         "sun.security.ec.SunEC",
    115         */
    116         "com.android.org.conscrypt.OpenSSLProvider",
    117         "com.android.org.bouncycastle.jce.provider.BouncyCastleProvider",
    118         "com.android.org.conscrypt.JSSEProvider",
    119         // END Android-changed: Use Conscrypt and BC, not the sun.security providers.
    120         BACKUP_PROVIDER_CLASSNAME,
    121     };
    122 
    123     // Return to Sun provider or its backup.
    124     // This method should only be called by
    125     // sun.security.util.ManifestEntryVerifier and java.security.SecureRandom.
    126     public static Provider getSunProvider() {
    127         try {
    128             Class<?> clazz = Class.forName(jarVerificationProviders[0]);
    129             return (Provider)clazz.newInstance();
    130         } catch (Exception e) {
    131             try {
    132                 Class<?> clazz = Class.forName(BACKUP_PROVIDER_CLASSNAME);
    133                 return (Provider)clazz.newInstance();
    134             } catch (Exception ee) {
    135                 throw new RuntimeException("Sun provider not found", e);
    136             }
    137         }
    138     }
    139 
    140     /**
    141      * Start JAR verification. This sets a special provider list for
    142      * the current thread. You MUST save the return value from this
    143      * method and you MUST call stopJarVerification() with that object
    144      * once you are done.
    145      */
    146     public static Object startJarVerification() {
    147         ProviderList currentList = getProviderList();
    148         ProviderList jarList = currentList.getJarList(jarVerificationProviders);
    149         // return the old thread-local provider list, usually null
    150         return beginThreadProviderList(jarList);
    151     }
    152 
    153     /**
    154      * Stop JAR verification. Call once you have completed JAR verification.
    155      */
    156     public static void stopJarVerification(Object obj) {
    157         // restore old thread-local provider list
    158         endThreadProviderList((ProviderList)obj);
    159     }
    160 
    161     /**
    162      * Return the current ProviderList. If the thread-local list is set,
    163      * it is returned. Otherwise, the system wide list is returned.
    164      */
    165     public static ProviderList getProviderList() {
    166         ProviderList list = getThreadProviderList();
    167         if (list == null) {
    168             list = getSystemProviderList();
    169         }
    170         return list;
    171     }
    172 
    173     /**
    174      * Set the current ProviderList. Affects the thread-local list if set,
    175      * otherwise the system wide list.
    176      */
    177     public static void setProviderList(ProviderList newList) {
    178         if (getThreadProviderList() == null) {
    179             setSystemProviderList(newList);
    180         } else {
    181             changeThreadProviderList(newList);
    182         }
    183     }
    184 
    185     /**
    186      * Get the full provider list with invalid providers (those that
    187      * could not be loaded) removed. This is the list we need to
    188      * present to applications.
    189      */
    190     public static ProviderList getFullProviderList() {
    191         ProviderList list;
    192         synchronized (Providers.class) {
    193             list = getThreadProviderList();
    194             if (list != null) {
    195                 ProviderList newList = list.removeInvalid();
    196                 if (newList != list) {
    197                     changeThreadProviderList(newList);
    198                     list = newList;
    199                 }
    200                 return list;
    201             }
    202         }
    203         list = getSystemProviderList();
    204         ProviderList newList = list.removeInvalid();
    205         if (newList != list) {
    206             setSystemProviderList(newList);
    207             list = newList;
    208         }
    209         return list;
    210     }
    211 
    212     private static ProviderList getSystemProviderList() {
    213         return providerList;
    214     }
    215 
    216     private static void setSystemProviderList(ProviderList list) {
    217         providerList = list;
    218     }
    219 
    220     public static ProviderList getThreadProviderList() {
    221         // avoid accessing the threadlocal if none are currently in use
    222         // (first use of ThreadLocal.get() for a Thread allocates a Map)
    223         if (threadListsUsed == 0) {
    224             return null;
    225         }
    226         return threadLists.get();
    227     }
    228 
    229     // Change the thread local provider list. Use only if the current thread
    230     // is already using a thread local list and you want to change it in place.
    231     // In other cases, use the begin/endThreadProviderList() methods.
    232     private static void changeThreadProviderList(ProviderList list) {
    233         threadLists.set(list);
    234     }
    235 
    236     /**
    237      * Methods to manipulate the thread local provider list. It is for use by
    238      * JAR verification (see above) and the SunJSSE FIPS mode only.
    239      *
    240      * It should be used as follows:
    241      *
    242      *   ProviderList list = ...;
    243      *   ProviderList oldList = Providers.beginThreadProviderList(list);
    244      *   try {
    245      *     // code that needs thread local provider list
    246      *   } finally {
    247      *     Providers.endThreadProviderList(oldList);
    248      *   }
    249      *
    250      */
    251 
    252     public static synchronized ProviderList beginThreadProviderList(ProviderList list) {
    253         if (ProviderList.debug != null) {
    254             ProviderList.debug.println("ThreadLocal providers: " + list);
    255         }
    256         ProviderList oldList = threadLists.get();
    257         threadListsUsed++;
    258         threadLists.set(list);
    259         return oldList;
    260     }
    261 
    262     public static synchronized void endThreadProviderList(ProviderList list) {
    263         if (list == null) {
    264             if (ProviderList.debug != null) {
    265                 ProviderList.debug.println("Disabling ThreadLocal providers");
    266             }
    267             threadLists.remove();
    268         } else {
    269             if (ProviderList.debug != null) {
    270                 ProviderList.debug.println
    271                     ("Restoring previous ThreadLocal providers: " + list);
    272             }
    273             threadLists.set(list);
    274         }
    275         threadListsUsed--;
    276     }
    277 
    278     // BEGIN Android-added: Check for requests of deprecated Bouncy Castle algorithms.
    279     // Beginning in Android P, Bouncy Castle versions of algorithms available through
    280     // Conscrypt are deprecated.  We will no longer supply them to applications
    281     // with a target API level of P or later, and will print a warning for applications
    282     // with a target API level before P.
    283     //
    284     // We only care about the system-provided Bouncy Castle provider; applications are allowed to
    285     // install their own copy of Bouncy Castle if they want to continue using those implementations.
    286 
    287     /**
    288      * Maximum target API level for which we will provide the deprecated Bouncy Castle algorithms.
    289      *
    290      * Only exists for testing and shouldn't be changed.
    291      *
    292      * @hide
    293      */
    294     public static final int DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION = 27;
    295 
    296     private static int maximumAllowableApiLevelForBcDeprecation =
    297             DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION;
    298 
    299     /**
    300      * Sets the target API level for BC deprecation, only for use in tests.
    301      *
    302      * @hide
    303      */
    304     public static void setMaximumAllowableApiLevelForBcDeprecation(int targetApiLevel) {
    305         maximumAllowableApiLevelForBcDeprecation = targetApiLevel;
    306     }
    307 
    308     /**
    309      * Returns the target API level for BC deprecation, only for use in tests.
    310      *
    311      * @hide
    312      */
    313     public static int getMaximumAllowableApiLevelForBcDeprecation() {
    314         return maximumAllowableApiLevelForBcDeprecation;
    315     }
    316 
    317     /**
    318      * Checks if the installed provider with the given name is the system-installed Bouncy
    319      * Castle provider.  If so, throws {@code NoSuchAlgorithmException} if the algorithm
    320      * being requested is deprecated and the application targets a late-enough API level.
    321      *
    322      * @hide
    323      */
    324     public static synchronized void checkBouncyCastleDeprecation(String provider,
    325             String service, String algorithm) throws NoSuchAlgorithmException {
    326         // Applications may install their own BC provider, only the algorithms from the system
    327         // provider are deprecated.
    328         if ("BC".equals(provider)
    329                 && providerList.getProvider(provider) == SYSTEM_BOUNCY_CASTLE_PROVIDER) {
    330             checkBouncyCastleDeprecation(service, algorithm);
    331         }
    332     }
    333 
    334     /**
    335      * Checks if the given provider is the system-installed Bouncy Castle provider.  If so,
    336      * throws {@code NoSuchAlgorithmException} if the algorithm being requested is deprecated
    337      * and the application targets a late-enough API level.
    338      *
    339      * @hide
    340      */
    341     public static synchronized void checkBouncyCastleDeprecation(Provider provider,
    342             String service, String algorithm) throws NoSuchAlgorithmException {
    343         // Applications may install their own BC provider, only the algorithms from the system
    344         // provider are deprecated.
    345         if (provider == SYSTEM_BOUNCY_CASTLE_PROVIDER) {
    346             checkBouncyCastleDeprecation(service, algorithm);
    347         }
    348     }
    349 
    350     // The set of algorithms that are deprecated.  This list is created using
    351     // libcore/tools/crypto/src/java/libcore/java/security/ProviderOverlap.java, with
    352     // additional Ciphers added manually (see comment below).
    353     private static final Set<String> DEPRECATED_ALGORITHMS = new HashSet<String>();
    354     static {
    355         DEPRECATED_ALGORITHMS.addAll(Arrays.asList(
    356                 "ALGORITHMPARAMETERS.1.2.840.113549.3.7",
    357                 "ALGORITHMPARAMETERS.2.16.840.1.101.3.4.1.2",
    358                 "ALGORITHMPARAMETERS.2.16.840.1.101.3.4.1.22",
    359                 "ALGORITHMPARAMETERS.2.16.840.1.101.3.4.1.26",
    360                 "ALGORITHMPARAMETERS.2.16.840.1.101.3.4.1.42",
    361                 "ALGORITHMPARAMETERS.2.16.840.1.101.3.4.1.46",
    362                 "ALGORITHMPARAMETERS.2.16.840.1.101.3.4.1.6",
    363                 "ALGORITHMPARAMETERS.AES",
    364                 "ALGORITHMPARAMETERS.DESEDE",
    365                 "ALGORITHMPARAMETERS.EC",
    366                 "ALGORITHMPARAMETERS.GCM",
    367                 "ALGORITHMPARAMETERS.OAEP",
    368                 "ALGORITHMPARAMETERS.TDEA",
    369                 "CERTIFICATEFACTORY.X.509",
    370                 "CERTIFICATEFACTORY.X509",
    371                 // List of Ciphers produced by ProviderOverlap:
    372                 "CIPHER.1.2.840.113549.3.4",
    373                 "CIPHER.2.16.840.1.101.3.4.1.26",
    374                 "CIPHER.2.16.840.1.101.3.4.1.46",
    375                 "CIPHER.2.16.840.1.101.3.4.1.6",
    376                 "CIPHER.AES/GCM/NOPADDING",
    377                 "CIPHER.ARC4",
    378                 "CIPHER.ARCFOUR",
    379                 "CIPHER.OID.1.2.840.113549.3.4",
    380                 "CIPHER.RC4",
    381                 // End of Ciphers produced by ProviderOverlap
    382                 // Additional ciphers transformations that will resolve to the same things as
    383                 // the automatically-produced overlap due to the Cipher transformation rules.
    384                 // These have been added manually.
    385                 "CIPHER.ARC4/ECB/NOPADDING",
    386                 "CIPHER.ARC4/NONE/NOPADDING",
    387                 "CIPHER.ARCFOUR/ECB/NOPADDING",
    388                 "CIPHER.ARCFOUR/NONE/NOPADDING",
    389                 "CIPHER.RC4/ECB/NOPADDING",
    390                 "CIPHER.RC4/NONE/NOPADDING",
    391                 // End of additional Ciphers
    392                 "KEYAGREEMENT.ECDH",
    393                 "KEYFACTORY.1.2.840.10045.2.1",
    394                 "KEYFACTORY.1.2.840.113549.1.1.1",
    395                 "KEYFACTORY.1.2.840.113549.1.1.7",
    396                 "KEYFACTORY.1.3.133.16.840.63.0.2",
    397                 "KEYFACTORY.2.5.8.1.1",
    398                 "KEYFACTORY.EC",
    399                 "KEYFACTORY.RSA",
    400                 "KEYGENERATOR.1.2.840.113549.2.10",
    401                 "KEYGENERATOR.1.2.840.113549.2.11",
    402                 "KEYGENERATOR.1.2.840.113549.2.7",
    403                 "KEYGENERATOR.1.2.840.113549.2.8",
    404                 "KEYGENERATOR.1.2.840.113549.2.9",
    405                 "KEYGENERATOR.1.3.6.1.5.5.8.1.1",
    406                 "KEYGENERATOR.1.3.6.1.5.5.8.1.2",
    407                 "KEYGENERATOR.2.16.840.1.101.3.4.2.1",
    408                 "KEYGENERATOR.AES",
    409                 "KEYGENERATOR.DESEDE",
    410                 "KEYGENERATOR.HMAC-MD5",
    411                 "KEYGENERATOR.HMAC-SHA1",
    412                 "KEYGENERATOR.HMAC-SHA224",
    413                 "KEYGENERATOR.HMAC-SHA256",
    414                 "KEYGENERATOR.HMAC-SHA384",
    415                 "KEYGENERATOR.HMAC-SHA512",
    416                 "KEYGENERATOR.HMAC/MD5",
    417                 "KEYGENERATOR.HMAC/SHA1",
    418                 "KEYGENERATOR.HMAC/SHA224",
    419                 "KEYGENERATOR.HMAC/SHA256",
    420                 "KEYGENERATOR.HMAC/SHA384",
    421                 "KEYGENERATOR.HMAC/SHA512",
    422                 "KEYGENERATOR.HMACMD5",
    423                 "KEYGENERATOR.HMACSHA1",
    424                 "KEYGENERATOR.HMACSHA224",
    425                 "KEYGENERATOR.HMACSHA256",
    426                 "KEYGENERATOR.HMACSHA384",
    427                 "KEYGENERATOR.HMACSHA512",
    428                 "KEYGENERATOR.TDEA",
    429                 "KEYPAIRGENERATOR.1.2.840.10045.2.1",
    430                 "KEYPAIRGENERATOR.1.2.840.113549.1.1.1",
    431                 "KEYPAIRGENERATOR.1.2.840.113549.1.1.7",
    432                 "KEYPAIRGENERATOR.1.3.133.16.840.63.0.2",
    433                 "KEYPAIRGENERATOR.2.5.8.1.1",
    434                 "KEYPAIRGENERATOR.EC",
    435                 "KEYPAIRGENERATOR.RSA",
    436                 "MAC.1.2.840.113549.2.10",
    437                 "MAC.1.2.840.113549.2.11",
    438                 "MAC.1.2.840.113549.2.7",
    439                 "MAC.1.2.840.113549.2.8",
    440                 "MAC.1.2.840.113549.2.9",
    441                 "MAC.1.3.6.1.5.5.8.1.1",
    442                 "MAC.1.3.6.1.5.5.8.1.2",
    443                 "MAC.2.16.840.1.101.3.4.2.1",
    444                 "MAC.HMAC-MD5",
    445                 "MAC.HMAC-SHA1",
    446                 "MAC.HMAC-SHA224",
    447                 "MAC.HMAC-SHA256",
    448                 "MAC.HMAC-SHA384",
    449                 "MAC.HMAC-SHA512",
    450                 "MAC.HMAC/MD5",
    451                 "MAC.HMAC/SHA1",
    452                 "MAC.HMAC/SHA224",
    453                 "MAC.HMAC/SHA256",
    454                 "MAC.HMAC/SHA384",
    455                 "MAC.HMAC/SHA512",
    456                 "MAC.HMACMD5",
    457                 "MAC.HMACSHA1",
    458                 "MAC.HMACSHA224",
    459                 "MAC.HMACSHA256",
    460                 "MAC.HMACSHA384",
    461                 "MAC.HMACSHA512",
    462                 "MAC.PBEWITHHMACSHA224",
    463                 "MAC.PBEWITHHMACSHA256",
    464                 "MAC.PBEWITHHMACSHA384",
    465                 "MAC.PBEWITHHMACSHA512",
    466                 "MESSAGEDIGEST.1.2.840.113549.2.5",
    467                 "MESSAGEDIGEST.1.3.14.3.2.26",
    468                 "MESSAGEDIGEST.2.16.840.1.101.3.4.2.1",
    469                 "MESSAGEDIGEST.2.16.840.1.101.3.4.2.2",
    470                 "MESSAGEDIGEST.2.16.840.1.101.3.4.2.3",
    471                 "MESSAGEDIGEST.2.16.840.1.101.3.4.2.4",
    472                 "MESSAGEDIGEST.MD5",
    473                 "MESSAGEDIGEST.SHA",
    474                 "MESSAGEDIGEST.SHA-1",
    475                 "MESSAGEDIGEST.SHA-224",
    476                 "MESSAGEDIGEST.SHA-256",
    477                 "MESSAGEDIGEST.SHA-384",
    478                 "MESSAGEDIGEST.SHA-512",
    479                 "MESSAGEDIGEST.SHA1",
    480                 "MESSAGEDIGEST.SHA224",
    481                 "MESSAGEDIGEST.SHA256",
    482                 "MESSAGEDIGEST.SHA384",
    483                 "MESSAGEDIGEST.SHA512",
    484                 "SECRETKEYFACTORY.DESEDE",
    485                 "SECRETKEYFACTORY.TDEA",
    486                 "SIGNATURE.1.2.840.10045.4.1",
    487                 "SIGNATURE.1.2.840.10045.4.3.1",
    488                 "SIGNATURE.1.2.840.10045.4.3.2",
    489                 "SIGNATURE.1.2.840.10045.4.3.3",
    490                 "SIGNATURE.1.2.840.10045.4.3.4",
    491                 "SIGNATURE.1.2.840.113549.1.1.11",
    492                 "SIGNATURE.1.2.840.113549.1.1.12",
    493                 "SIGNATURE.1.2.840.113549.1.1.13",
    494                 "SIGNATURE.1.2.840.113549.1.1.14",
    495                 "SIGNATURE.1.2.840.113549.1.1.4",
    496                 "SIGNATURE.1.2.840.113549.1.1.5",
    497                 "SIGNATURE.1.3.14.3.2.29",
    498                 "SIGNATURE.ECDSA",
    499                 "SIGNATURE.ECDSAWITHSHA1",
    500                 "SIGNATURE.MD5/RSA",
    501                 "SIGNATURE.MD5WITHRSA",
    502                 "SIGNATURE.MD5WITHRSAENCRYPTION",
    503                 "SIGNATURE.NONEWITHECDSA",
    504                 "SIGNATURE.OID.1.2.840.10045.4.3.1",
    505                 "SIGNATURE.OID.1.2.840.10045.4.3.2",
    506                 "SIGNATURE.OID.1.2.840.10045.4.3.3",
    507                 "SIGNATURE.OID.1.2.840.10045.4.3.4",
    508                 "SIGNATURE.OID.1.2.840.113549.1.1.11",
    509                 "SIGNATURE.OID.1.2.840.113549.1.1.12",
    510                 "SIGNATURE.OID.1.2.840.113549.1.1.13",
    511                 "SIGNATURE.OID.1.2.840.113549.1.1.14",
    512                 "SIGNATURE.OID.1.2.840.113549.1.1.4",
    513                 "SIGNATURE.OID.1.2.840.113549.1.1.5",
    514                 "SIGNATURE.OID.1.3.14.3.2.29",
    515                 "SIGNATURE.SHA1/RSA",
    516                 "SIGNATURE.SHA1WITHECDSA",
    517                 "SIGNATURE.SHA1WITHRSA",
    518                 "SIGNATURE.SHA1WITHRSAENCRYPTION",
    519                 "SIGNATURE.SHA224/ECDSA",
    520                 "SIGNATURE.SHA224/RSA",
    521                 "SIGNATURE.SHA224WITHECDSA",
    522                 "SIGNATURE.SHA224WITHRSA",
    523                 "SIGNATURE.SHA224WITHRSAENCRYPTION",
    524                 "SIGNATURE.SHA256/ECDSA",
    525                 "SIGNATURE.SHA256/RSA",
    526                 "SIGNATURE.SHA256WITHECDSA",
    527                 "SIGNATURE.SHA256WITHRSA",
    528                 "SIGNATURE.SHA256WITHRSAENCRYPTION",
    529                 "SIGNATURE.SHA384/ECDSA",
    530                 "SIGNATURE.SHA384/RSA",
    531                 "SIGNATURE.SHA384WITHECDSA",
    532                 "SIGNATURE.SHA384WITHRSA",
    533                 "SIGNATURE.SHA384WITHRSAENCRYPTION",
    534                 "SIGNATURE.SHA512/ECDSA",
    535                 "SIGNATURE.SHA512/RSA",
    536                 "SIGNATURE.SHA512WITHECDSA",
    537                 "SIGNATURE.SHA512WITHRSA",
    538                 "SIGNATURE.SHA512WITHRSAENCRYPTION"
    539         ));
    540     }
    541 
    542     /**
    543      * Throws an exception or logs a warning if the supplied service and algorithm identify
    544      * a deprecated algorithm from Bouncy Castle, depending on the application's target API level.
    545      * Only called if we have already determined that the request is for the system Bouncy Castle
    546      * provider.
    547      */
    548     private static void checkBouncyCastleDeprecation(String service, String algorithm)
    549             throws NoSuchAlgorithmException {
    550         String key = service + "." + algorithm;
    551         if (DEPRECATED_ALGORITHMS.contains(key.toUpperCase(Locale.US))) {
    552             if (VMRuntime.getRuntime().getTargetSdkVersion()
    553                     <= maximumAllowableApiLevelForBcDeprecation) {
    554                 // This application is allowed to access these functions, only print a warning
    555                 System.logE(" ******** DEPRECATED FUNCTIONALITY ********");
    556                 System.logE(" * The implementation of the " + key + " algorithm from");
    557                 System.logE(" * the BC provider is deprecated in this version of Android.");
    558                 System.logE(" * It will be removed in a future version of Android and your");
    559                 System.logE(" * application will no longer be able to request it.  Please see");
    560                 System.logE(" * https://android-developers.googleblog.com/2018/03/cryptography-changes-in-android-p.html");
    561                 System.logE(" * for more details.");
    562             } else {
    563                 throw new NoSuchAlgorithmException("The BC provider no longer provides an"
    564                         + " implementation for " + key + ".  Please see"
    565                         + " https://android-developers.googleblog.com/2018/03/cryptography-changes-in-android-p.html"
    566                         + " for more details.");
    567             }
    568         }
    569     }
    570 
    571 }
    572