• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Providers()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.
getSunProvider()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      */
startJarVerification()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      */
stopJarVerification(Object obj)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      */
getProviderList()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      */
setProviderList(ProviderList newList)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      */
getFullProviderList()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 
getSystemProviderList()212     private static ProviderList getSystemProviderList() {
213         return providerList;
214     }
215 
setSystemProviderList(ProviderList list)216     private static void setSystemProviderList(ProviderList list) {
217         providerList = list;
218     }
219 
getThreadProviderList()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.
changeThreadProviderList(ProviderList list)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 
beginThreadProviderList(ProviderList list)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 
endThreadProviderList(ProviderList list)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      */
setMaximumAllowableApiLevelForBcDeprecation(int targetApiLevel)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      */
getMaximumAllowableApiLevelForBcDeprecation()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      */
checkBouncyCastleDeprecation(String provider, String service, String algorithm)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      */
checkBouncyCastleDeprecation(Provider provider, String service, String algorithm)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      */
checkBouncyCastleDeprecation(String service, String algorithm)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     // END Android-added: Check for requests of deprecated Bouncy Castle algorithms.
571 
572 }
573