Merge "Disable from-text stub generation for conscrypt.module.intra.core.api" into main
diff --git a/Android.bp b/Android.bp
index 97bf195..63e27e9 100644
--- a/Android.bp
+++ b/Android.bp
@@ -145,6 +145,7 @@
name: "libconscrypt_openjdk_jni",
visibility: [
"//build/make/tools/signapk",
+ "//cts/hostsidetests/library", // from CtsUseNativeLibraryBuildPackage
"//tools/apksig",
"//vendor:__subpackages__",
],
@@ -184,6 +185,31 @@
},
}
+aconfig_declarations {
+ name: "conscrypt-aconfig-flags",
+ package: "com.android.org.conscrypt",
+ container: "com.android.conscrypt",
+ srcs: ["conscrypt.aconfig"],
+}
+
+java_aconfig_library {
+ name: "conscrypt-aconfig-flags-lib",
+ aconfig_declarations: "conscrypt-aconfig-flags",
+ system_modules: "art-module-intra-core-api-stubs-system-modules",
+ libs: [
+ "aconfig-annotations-lib-sdk-none",
+ "unsupportedappusage",
+ ],
+ sdk_version: "none",
+ patch_module: "java.base",
+ apex_available: [
+ "com.android.conscrypt",
+ ],
+ min_sdk_version: "30",
+ installable: false,
+ visibility: ["//visibility:private"],
+}
+
cc_binary_host {
name: "conscrypt_generate_constants",
srcs: ["constants/src/gen/cpp/generate_constants.cc"],
@@ -238,8 +264,8 @@
"com.android.conscrypt",
"test_com.android.conscrypt",
],
- // Conscrypt should support Q
- min_sdk_version: "29",
+ // Conscrypt should support R
+ min_sdk_version: "30",
installable: true,
// Hostdex is only for ART testing on host: ART build file has its
@@ -252,6 +278,9 @@
],
libs: ["unsupportedappusage"],
+ static_libs: [
+ "conscrypt-aconfig-flags-lib",
+ ],
// Conscrypt can be updated independently from the other core libraries so it must only depend
// on public SDK and intra-core APIs.
@@ -276,9 +305,6 @@
"android.net.ssl",
"com.android.org.conscrypt",
],
- lint: {
- baseline_filename: "lint-baseline.xml",
- },
}
// Java library for use on host, e.g. by robolectric.
@@ -295,14 +321,11 @@
],
sdk_version: "none",
system_modules: "none",
- lint: {
- baseline_filename: "lint-baseline.xml",
- },
}
// Referenced implicitly from conscrypt.module.platform.api.
filegroup {
- name: "conscrypt.module.platform.api.api.public.latest",
+ name: "conscrypt.module.platform.api.api.combined.public.latest",
srcs: [
"api/platform/last-api.txt",
],
@@ -310,7 +333,7 @@
// Referenced implicitly from conscrypt.module.platform.api.
filegroup {
- name: "conscrypt.module.platform.api-removed.api.public.latest",
+ name: "conscrypt.module.platform.api-removed.api.combined.public.latest",
srcs: [
"api/platform/last-removed.txt",
],
@@ -374,9 +397,6 @@
dist_stem: "conscrypt-coreplatform",
// TODO: remove this when Conscrypt's @CorePlatformApi has been migrated to @SystemApi
unsafe_ignore_missing_latest_api: true,
- lint: {
- baseline_filename: "lint-baseline.xml",
- },
}
// A library containing the public API stubs of the Conscrypt module.
@@ -431,14 +451,11 @@
sdk_version: "none",
system_modules: "art-module-public-api-stubs-system-modules",
dist_group: "android",
- lint: {
- baseline_filename: "lint-baseline.xml",
- },
}
// Referenced implicitly from conscrypt.module.intra.core.api.
filegroup {
- name: "conscrypt.module.intra.core.api.api.public.latest",
+ name: "conscrypt.module.intra.core.api.api.combined.public.latest",
srcs: [
"api/intra/last-api.txt",
],
@@ -446,7 +463,7 @@
// Referenced implicitly from conscrypt.module.intra.core.api.
filegroup {
- name: "conscrypt.module.intra.core.api-removed.api.public.latest",
+ name: "conscrypt.module.intra.core.api-removed.api.combined.public.latest",
srcs: [
"api/intra/last-removed.txt",
],
@@ -499,9 +516,6 @@
// Don't copy any output files to the dist.
no_dist: true,
- lint: {
- baseline_filename: "lint-baseline.xml",
- },
}
// Platform conscrypt crypto JNI library
@@ -556,7 +570,7 @@
"com.android.conscrypt",
"test_com.android.conscrypt",
],
- min_sdk_version: "29",
+ min_sdk_version: "30",
}
// Unbundled Conscrypt jar for use by signapk and apksigner tool
@@ -589,9 +603,6 @@
},
// Make sure that this will be added to the sdk snapshot for S.
min_sdk_version: "S",
- lint: {
- baseline_filename: "lint-baseline.xml",
- },
}
// Interim library for accessing pseudo-JCA Conscrypt APIs such as HPKE until
@@ -640,6 +651,25 @@
stl: "c++_shared",
}
+java_library {
+ name: "conscrypt-test-support",
+ visibility: [
+ "//frameworks/base/apct-tests/perftests/core",
+ ],
+ device_supported: true,
+ host_supported: true,
+ srcs: [
+ "testing/src/main/java/**/*.java",
+ ":conscrypt-unbundled_generated_constants",
+ ],
+ libs: [
+ "junit",
+ "bouncycastle-unbundled",
+ "bouncycastle-bcpkix-unbundled",
+ "bouncycastle-ocsp-unbundled",
+ ],
+}
+
// Make the conscrypt-tests library.
java_test {
name: "conscrypt-tests",
@@ -692,9 +722,6 @@
},
},
java_version: "1.8",
- lint: {
- baseline_filename: "lint-baseline.xml",
- },
}
// Make the conscrypt-benchmarks library.
@@ -732,9 +759,6 @@
},
},
java_version: "1.8",
- lint: {
- baseline_filename: "lint-baseline.xml",
- },
}
// Device SDK exposed by the Conscrypt module.
diff --git a/TEST_MAPPING b/TEST_MAPPING
new file mode 100644
index 0000000..cffa5f4
--- /dev/null
+++ b/TEST_MAPPING
@@ -0,0 +1,35 @@
+{
+ "presubmit": [
+ {
+ "name": "CtsLibcoreTestCases",
+ "options": [
+ {
+ "include-filter": "com.android.org.conscrypt"
+ },
+ {
+ "include-filter": "libcore.java.security"
+ },
+ {
+ "include-filter": "libcore.javax.net"
+ },
+ {
+ "include-filter": "libcore.java.net"
+ },
+ {
+ "include-filter": "android.net.ssl"
+ }
+ ]
+ },
+ {
+ "name": "CtsSecurityTestCases",
+ "options": [
+ {
+ "include-filter": "android.security.cts.CertBlocklistTest"
+ },
+ {
+ "include-filter": "android.security.cts.CertBlocklistFileTest"
+ }
+ ]
+ }
+ ]
+}
diff --git a/android/src/main/java/org/conscrypt/Platform.java b/android/src/main/java/org/conscrypt/Platform.java
index 3940f97..5b0ebed 100644
--- a/android/src/main/java/org/conscrypt/Platform.java
+++ b/android/src/main/java/org/conscrypt/Platform.java
@@ -459,116 +459,6 @@
}
}
- /**
- * Wraps an old AndroidOpenSSL key instance. This is not needed on platform
- * builds since we didn't backport, so return null. This code is from
- * Chromium's net/android/java/src/org/chromium/net/DefaultAndroidKeyStore.java
- */
- @SuppressWarnings("LiteralClassName")
- public static OpenSSLKey wrapRsaKey(PrivateKey javaKey) {
- // This fixup only applies to pre-JB-MR1
- if (Build.VERSION.SDK_INT >= 17) {
- return null;
- }
-
- // First, check that this is a proper instance of OpenSSLRSAPrivateKey
- // or one of its sub-classes.
- Class<?> superClass;
- try {
- superClass =
- Class.forName("org.apache.harmony.xnet.provider.jsse.OpenSSLRSAPrivateKey");
- } catch (Exception e) {
- // This may happen if the target device has a completely different
- // implementation of the java.security APIs, compared to vanilla
- // Android. Highly unlikely, but still possible.
- Log.e(TAG, "Cannot find system OpenSSLRSAPrivateKey class: " + e);
- return null;
- }
- if (!superClass.isInstance(javaKey)) {
- // This may happen if the PrivateKey was not created by the
- // Conscrypt provider, which should be the default. That could happen if an
- // OEM decided to implement a different default provider. Also highly unlikely.
- Log.e(TAG,
- "Private key is not an OpenSSLRSAPrivateKey instance, its class name is:"
- + javaKey.getClass().getCanonicalName());
- return null;
- }
-
- try {
- // Use reflection to invoke the 'getOpenSSLKey()' method on
- // the private key. This returns another Java object that wraps
- // a native EVP_PKEY. Note that the method is final, so calling
- // the superclass implementation is ok.
- Method getKey = superClass.getDeclaredMethod("getOpenSSLKey");
- getKey.setAccessible(true);
- Object opensslKey = null;
- try {
- opensslKey = getKey.invoke(javaKey);
- } finally {
- getKey.setAccessible(false);
- }
- if (opensslKey == null) {
- // Bail when detecting OEM "enhancement".
- Log.e(TAG, "Could not getOpenSSLKey on instance: " + javaKey.toString());
- return null;
- }
-
- // Use reflection to invoke the 'getPkeyContext' method on the
- // result of the getOpenSSLKey(). This is an 32-bit integer
- // which is the address of an EVP_PKEY object. Note that this
- // method these days returns a 64-bit long, but since this code
- // path is used for older Android versions, it may still return
- // a 32-bit int here. To be on the safe side, we cast the return
- // value via Number rather than directly to Integer or Long.
- Method getPkeyContext;
- try {
- getPkeyContext = opensslKey.getClass().getDeclaredMethod("getPkeyContext");
- } catch (Exception e) {
- // Bail here too, something really not working as expected.
- Log.e(TAG, "No getPkeyContext() method on OpenSSLKey member:" + e);
- return null;
- }
- getPkeyContext.setAccessible(true);
- long evp_pkey = 0;
- try {
- evp_pkey = ((Number) getPkeyContext.invoke(opensslKey)).longValue();
- } finally {
- getPkeyContext.setAccessible(false);
- }
- if (evp_pkey == 0) {
- // The PrivateKey is probably rotten for some reason.
- Log.e(TAG, "getPkeyContext() returned null");
- return null;
- }
- return new OpenSSLKey(evp_pkey);
- } catch (Exception e) {
- Log.e(TAG, "Error during conversion of privatekey instance: " + javaKey.toString(), e);
- return null;
- }
- }
-
- /**
- * Logs to the system EventLog system.
- */
- @SuppressWarnings("LiteralClassName")
- public static void logEvent(String message) {
- try {
- Class<?> processClass = Class.forName("android.os.Process");
- Object processInstance = processClass.getDeclaredConstructor().newInstance();
- Method myUidMethod = processClass.getMethod("myUid", (Class[]) null);
- int uid = (Integer) myUidMethod.invoke(processInstance);
-
- Class<?> eventLogClass = Class.forName("android.util.EventLog");
- Object eventLogInstance = eventLogClass.getDeclaredConstructor().newInstance();
- Method writeEventMethod =
- eventLogClass.getMethod("writeEvent", Integer.TYPE, Object[].class);
- writeEventMethod.invoke(eventLogInstance, 0x534e4554 /* SNET */,
- new Object[] {"conscrypt", uid, message});
- } catch (Exception e) {
- // Fail silently
- }
- }
-
static SSLEngine wrapEngine(ConscryptEngine engine) {
// For now, don't wrap on Android.
return engine;
@@ -1085,4 +975,12 @@
public static boolean isTlsV1Deprecated() {
return true;
}
+
+ public static boolean isTlsV1Filtered() {
+ return false;
+ }
+
+ public static boolean isTlsV1Supported() {
+ return false;
+ }
}
diff --git a/apex/Android.bp b/apex/Android.bp
index 2271655..ad85aed 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -78,148 +78,16 @@
visibility: [
"//external/conscrypt",
"//vendor:__subpackages__",
+ "//packages/modules/common/build",
],
defaults: ["com.android.conscrypt-defaults"],
manifest: "apex_manifest.json",
binaries: ["boringssl_self_test"],
prebuilts: [
"com.android.conscrypt.ld.config.txt",
- "target-cacert-apex-01419da9.0",
- "target-cacert-apex-04f60c28.0",
- "target-cacert-apex-0d69c7e1.0",
- "target-cacert-apex-10531352.0",
- "target-cacert-apex-1ae85e5e.0",
- "target-cacert-apex-1b0f7e5c.0",
- "target-cacert-apex-1df5a75f.0",
- "target-cacert-apex-1e1eab7c.0",
- "target-cacert-apex-1e8e7201.0",
- "target-cacert-apex-1ec40989.0",
- "target-cacert-apex-1f58a078.0",
- "target-cacert-apex-219d9499.0",
- "target-cacert-apex-23f4c490.0",
- "target-cacert-apex-252252d2.0",
- "target-cacert-apex-2add47b6.0",
- "target-cacert-apex-2d9dafe4.0",
- "target-cacert-apex-302904dd.0",
- "target-cacert-apex-304d27c3.0",
- "target-cacert-apex-31188b5e.0",
- "target-cacert-apex-33ee480d.0",
- "target-cacert-apex-35105088.0",
- "target-cacert-apex-399e7759.0",
- "target-cacert-apex-3ad48a91.0",
- "target-cacert-apex-3c860d51.0",
- "target-cacert-apex-3c899c73.0",
- "target-cacert-apex-3c9a4d3b.0",
- "target-cacert-apex-3e7271e8.0",
- "target-cacert-apex-41a3f684.0",
- "target-cacert-apex-455f1b52.0",
- "target-cacert-apex-48a195d8.0",
- "target-cacert-apex-4be590e0.0",
- "target-cacert-apex-4c3982f2.0",
- "target-cacert-apex-5046c355.0",
- "target-cacert-apex-52b525c7.0",
- "target-cacert-apex-53a1b57a.0",
- "target-cacert-apex-583d0756.0",
- "target-cacert-apex-5a3f0ff8.0",
- "target-cacert-apex-5acf816d.0",
- "target-cacert-apex-5f47b495.0",
- "target-cacert-apex-5f9a69fa.0",
- "target-cacert-apex-5fdd185d.0",
- "target-cacert-apex-60afe812.0",
- "target-cacert-apex-6187b673.0",
- "target-cacert-apex-63a2c897.0",
- "target-cacert-apex-69105f4f.0",
- "target-cacert-apex-6b03dec0.0",
- "target-cacert-apex-6f7454b3.0",
- "target-cacert-apex-75680d2e.0",
- "target-cacert-apex-76579174.0",
- "target-cacert-apex-7892ad52.0",
- "target-cacert-apex-7a7c655d.0",
- "target-cacert-apex-7a819ef2.0",
- "target-cacert-apex-7e067d03.0",
- "target-cacert-apex-81b9768f.0",
- "target-cacert-apex-82223c44.0",
- "target-cacert-apex-83e9984f.0",
- "target-cacert-apex-85cde254.0",
- "target-cacert-apex-86212b19.0",
- "target-cacert-apex-869fbf79.0",
- "target-cacert-apex-8794b4e3.0",
- "target-cacert-apex-882de061.0",
- "target-cacert-apex-88950faa.0",
- "target-cacert-apex-89c02a45.0",
- "target-cacert-apex-8d6437c3.0",
- "target-cacert-apex-9282e51c.0",
- "target-cacert-apex-9339512a.0",
- "target-cacert-apex-93851c9e.0",
- "target-cacert-apex-9479c8c3.0",
- "target-cacert-apex-9576d26b.0",
- "target-cacert-apex-9591a472.0",
- "target-cacert-apex-95aff9e3.0",
- "target-cacert-apex-985c1f52.0",
- "target-cacert-apex-99e1b953.0",
- "target-cacert-apex-9aef356c.0",
- "target-cacert-apex-9d6523ce.0",
- "target-cacert-apex-a2c66da8.0",
- "target-cacert-apex-a3896b44.0",
- "target-cacert-apex-a716d4ed.0",
- "target-cacert-apex-a81e292b.0",
- "target-cacert-apex-a9d40e02.0",
- "target-cacert-apex-ab5346f4.0",
- "target-cacert-apex-ab59055e.0",
- "target-cacert-apex-b0ed035a.0",
- "target-cacert-apex-b0f3e76e.0",
- "target-cacert-apex-b30d5fda.0",
- "target-cacert-apex-b3fb433b.0",
- "target-cacert-apex-b74d2bd5.0",
- "target-cacert-apex-b7db1890.0",
- "target-cacert-apex-b872f2b4.0",
- "target-cacert-apex-b92fd57f.0",
- "target-cacert-apex-b936d1c6.0",
- "target-cacert-apex-bc3f2570.0",
- "target-cacert-apex-bd43e1dd.0",
- "target-cacert-apex-bdacca6f.0",
- "target-cacert-apex-bf64f35b.0",
- "target-cacert-apex-c44cc0c0.0",
- "target-cacert-apex-c491639e.0",
- "target-cacert-apex-c559d742.0",
- "target-cacert-apex-c7f1359b.0",
- "target-cacert-apex-c90bc37d.0",
- "target-cacert-apex-cb1c3204.0",
- "target-cacert-apex-ccc52f49.0",
- "target-cacert-apex-cf701eeb.0",
- "target-cacert-apex-d06393bb.0",
- "target-cacert-apex-d16a5865.0",
- "target-cacert-apex-d16a5865.1",
- "target-cacert-apex-d18e9066.0",
- "target-cacert-apex-d39b0a2c.0",
- "target-cacert-apex-d41b5e2a.0",
- "target-cacert-apex-d4c339cb.0",
- "target-cacert-apex-d59297b8.0",
- "target-cacert-apex-d7746a63.0",
- "target-cacert-apex-d96b65e2.0",
- "target-cacert-apex-da7377f6.0",
- "target-cacert-apex-dbc54cab.0",
- "target-cacert-apex-dbff3a01.0",
- "target-cacert-apex-dc99f41e.0",
- "target-cacert-apex-dfc0fe80.0",
- "target-cacert-apex-e13665f9.0",
- "target-cacert-apex-e442e424.0",
- "target-cacert-apex-e48193cf.0",
- "target-cacert-apex-e7c037b4.0",
- "target-cacert-apex-e8651083.0",
- "target-cacert-apex-ed39abd0.0",
- "target-cacert-apex-edcbddb5.0",
- "target-cacert-apex-ee532fd5.0",
- "target-cacert-apex-f013ecaf.0",
- "target-cacert-apex-f058632f.0",
- "target-cacert-apex-f0cd152c.0",
- "target-cacert-apex-f459871d.0",
- "target-cacert-apex-f8fc53da.0",
- "target-cacert-apex-fb5fa911.0",
- "target-cacert-apex-fd08c599.0",
- "target-cacert-apex-fde84897.0",
- "target-cacert-apex-ffa7f1eb.0",
+ "cacerts_apex",
],
+ min_sdk_version: "30",
}
// Encapsulate the contributions made by the com.android.conscrypt to the bootclasspath.
diff --git a/apex/AndroidManifest.xml b/apex/AndroidManifest.xml
index a38cb9b..db47782 100644
--- a/apex/AndroidManifest.xml
+++ b/apex/AndroidManifest.xml
@@ -21,11 +21,4 @@
<!--
* API levels the Conscrypt APEX is known to work with.
-->
- <!-- TODO: Uncomment this when the R API level is fixed. b/148281152 -->
- <!--uses-sdk
- android:minSdkVersion="29"
- android:maxSdkVersion="29"
- android:targetSdkVersion="29"
- />
- -->
</manifest>
diff --git a/apex/ca-certificates/Android.bp b/apex/ca-certificates/Android.bp
index e109a94..25cb06b 100644
--- a/apex/ca-certificates/Android.bp
+++ b/apex/ca-certificates/Android.bp
@@ -29,10 +29,7 @@
license_text: [],
}
-// This is a temporary solution for adding certificates to the apex.
-ca_certificates_apex {
+prebuilt_etc_cacerts {
name: "cacerts_apex",
- src_dir: "files",
- dest_dir: "",
- module_name_prefix: "target-cacert-apex-",
+ srcs: ["files/*"],
}
diff --git a/apex/ca-certificates/files/073bfcc5.0 b/apex/ca-certificates/files/073bfcc5.0
new file mode 100644
index 0000000..719279b
--- /dev/null
+++ b/apex/ca-certificates/files/073bfcc5.0
@@ -0,0 +1,57 @@
+-----BEGIN CERTIFICATE-----
+MIICVTCCAdygAwIBAgIUTyNkuI6XY57GU4HBdk7LKnQV1tcwCgYIKoZIzj0EAwMw
+WjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMs
+IEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHNDAeFw0y
+MTA1MjAwMjEwMjJaFw00NjA1MTkwMjEwMjJaMFoxCzAJBgNVBAYTAkNOMSUwIwYD
+VQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDDBtUcnVz
+dEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATx
+s8045CVD5d4ZCbuBeaIVXxVjAd7Cq92zphtnS4CDr5nLrBfbK5bKfFJV4hrhPVbw
+LxYI+hW8m7tH5j/uqOFMjPXTNvk4XatwmkcN4oFBButJ+bAp3TPsUKV/eSm4IJij
+YzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUpbtKl86zK3+kMd6Xg1mD
+pm9xy94wHQYDVR0OBBYEFKW7SpfOsyt/pDHel4NZg6ZvccveMA4GA1UdDwEB/wQE
+AwIBBjAKBggqhkjOPQQDAwNnADBkAjBe8usGzEkxn0AAbbd+NvBNEU/zy4k6LHiR
+UKNbwMp1JvK/kF0LgoxgKJ/GcJpo5PECMFxYDlZ2z1jD1xCMuo6u47xkdUfFVZDj
+/bpV6wfEU6s3qe4hsiFbYI89MvHVI5TWWA==
+-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 4f:23:64:b8:8e:97:63:9e:c6:53:81:c1:76:4e:cb:2a:74:15:d6:d7
+ Signature Algorithm: ecdsa-with-SHA384
+ Issuer: C=CN, O=TrustAsia Technologies, Inc., CN=TrustAsia Global Root CA G4
+ Validity
+ Not Before: May 20 02:10:22 2021 GMT
+ Not After : May 19 02:10:22 2046 GMT
+ Subject: C=CN, O=TrustAsia Technologies, Inc., CN=TrustAsia Global Root CA G4
+ Subject Public Key Info:
+ Public Key Algorithm: id-ecPublicKey
+ Public-Key: (384 bit)
+ pub:
+ 04:f1:b3:cd:38:e4:25:43:e5:de:19:09:bb:81:79:
+ a2:15:5f:15:63:01:de:c2:ab:dd:b3:a6:1b:67:4b:
+ 80:83:af:99:cb:ac:17:db:2b:96:ca:7c:52:55:e2:
+ 1a:e1:3d:56:f0:2f:16:08:fa:15:bc:9b:bb:47:e6:
+ 3f:ee:a8:e1:4c:8c:f5:d3:36:f9:38:5d:ab:70:9a:
+ 47:0d:e2:81:41:06:eb:49:f9:b0:29:dd:33:ec:50:
+ a5:7f:79:29:b8:20:98
+ ASN1 OID: secp384r1
+ NIST CURVE: P-384
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Authority Key Identifier:
+ A5:BB:4A:97:CE:B3:2B:7F:A4:31:DE:97:83:59:83:A6:6F:71:CB:DE
+ X509v3 Subject Key Identifier:
+ A5:BB:4A:97:CE:B3:2B:7F:A4:31:DE:97:83:59:83:A6:6F:71:CB:DE
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ Signature Algorithm: ecdsa-with-SHA384
+ Signature Value:
+ 30:64:02:30:5e:f2:eb:06:cc:49:31:9f:40:00:6d:b7:7e:36:
+ f0:4d:11:4f:f3:cb:89:3a:2c:78:91:50:a3:5b:c0:ca:75:26:
+ f2:bf:90:5d:0b:82:8c:60:28:9f:c6:70:9a:68:e4:f1:02:30:
+ 5c:58:0e:56:76:cf:58:c3:d7:10:8c:ba:8e:ae:e3:bc:64:75:
+ 47:c5:55:90:e3:fd:ba:55:eb:07:c4:53:ab:37:a9:ee:21:b2:
+ 21:5b:60:8f:3d:32:f1:d5:23:94:d6:58
+SHA1 Fingerprint=57:73:A5:61:5D:80:B2:E6:AC:38:82:FC:68:07:31:AC:9F:B5:92:5A
diff --git a/apex/ca-certificates/files/128f4b91.0 b/apex/ca-certificates/files/128f4b91.0
new file mode 100644
index 0000000..fe417f1
--- /dev/null
+++ b/apex/ca-certificates/files/128f4b91.0
@@ -0,0 +1,121 @@
+-----BEGIN CERTIFICATE-----
+MIIFZDCCA0ygAwIBAgIQU9XP5hmTC/srBRLYwiqipDANBgkqhkiG9w0BAQwFADBM
+MS4wLAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgUlNBIFRMUyAyMDIx
+MQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTIxMTBaFw00
+MTA0MTcwOTIxMDlaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBD
+QSBSU0EgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMIICIjAN
+BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtoAOxHm9BYx9sKOdTSJNy/BBl01Z
+4NH+VoyX8te9j2y3I49f1cTYQcvyAh5x5en2XssIKl4w8i1mx4QbZFc4nXUtVsYv
+Ye+W/CBGvevUez8/fEc4BKkbqlLfEzfTFRVOvV98r61jx3ncCHvVoOX3W3WsgFWZ
+kmGbzSoXfduP9LVq6hdKZChmFSlsAvFr1bqjM9xaZ6cF4r9lthawEO3NUDPJcFDs
+GY6wx/J0W2tExn2WuZgIWWbeKQGb9Cpt0xU6kGpn8bRrZtkh68rZYnxGEFzedUln
+nkL5/nWpo63/dgpnQOPF943HhZpZnmKaau1Fh5hnstVKPNe0OwANwI8f4UDErmwh
+3El+fsqyjW22v5MvoVw+j8rtgI5Y4dtXz4U2OLJxpAmMkokIiEjxQGMYsluMWuPD
+0xeqqxmjLBvk1cbiZnrXghmmOxYsL3GHX0WelXOTwkKBIROW1527k2gV+p2kHYzy
+geBYBr3JtuP2iV2J+axEoctr+hbxx1A9JNr3w+SH1VbxT5Aw+kUJWdo0zuATHAR8
+ANSbhqRAvNncTFd+rrcztl524WWLZt+NyteYr842mIycg5kDcPOvdO3GDjbnvezB
+c6eUWsuSZIKmAMFwoW4sKeFYV+xafJlrJaSQOoD0IJ2azsct+bJLKZWD6TWNp0lI
+pw9MGZHQ9b8Q4HECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+dEmZ0f+0emhFdcN+tNzMzjkz2ggwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB
+DAUAA4ICAQAjQ1MkYlxt/T7Cz1UAbMVWiLkO3TriJQ2VSpfKgInuKs1l+NsW4AmS
+4BjHeJi78+xCUvuppILXTdiK/ORO/auQxDh1MoSf/7OwKwIzNsAQkG8dnK/haZPs
+o0UvFJ/1TCplQ3IM98P4lYsU84UgYt1UU90s3BiVaU+DR3BAM1h3Egyi61IxHkzJ
+qM7F78PRreBrAwA0JrRUITWXAdxfG/F851X6LWh3e9NpzNMOa7pNdkTWwhWaJuyw
+xfW70Xp0wmzNxbVe9kzmWy2B27O3Opee7c9GslA9hGCZcbUztVdF5kJHdWoOsAgM
+rr3e97sPWD2PAzHoPYJQyi9eDF20l74gNAf0xBLh7tew2VktafcxBPTy+av5EzH4
+AXcOPUIjJsyacmdRIXrMPIWo6iFqO9taPKU0nprALN+AnCng33eU0aKAQv9qTFsR
+0PXNor6uzFFcw9VUewyu1rkGd4Di7wcaaMxZUa1+XGdrudviB0JbuAEFWDlN5LuY
+o7Ey7Nmj1m+UI/87tyll5gfp77YZ6ufCOB0yiJA8EytuzO+rdwY0d4RPcuSBhPm5
+dDTedk+SKlOxJTnbPP/lPqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcE
+oji2jbDwN/zIIX8/syQbPYtuzE2wFg2WHYMfRsCbvUOZ58SWLs5fyQ==
+-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 53:d5:cf:e6:19:93:0b:fb:2b:05:12:d8:c2:2a:a2:a4
+ Signature Algorithm: sha384WithRSAEncryption
+ Issuer: CN=Atos TrustedRoot Root CA RSA TLS 2021, O=Atos, C=DE
+ Validity
+ Not Before: Apr 22 09:21:10 2021 GMT
+ Not After : Apr 17 09:21:09 2041 GMT
+ Subject: CN=Atos TrustedRoot Root CA RSA TLS 2021, O=Atos, C=DE
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (4096 bit)
+ Modulus:
+ 00:b6:80:0e:c4:79:bd:05:8c:7d:b0:a3:9d:4d:22:
+ 4d:cb:f0:41:97:4d:59:e0:d1:fe:56:8c:97:f2:d7:
+ bd:8f:6c:b7:23:8f:5f:d5:c4:d8:41:cb:f2:02:1e:
+ 71:e5:e9:f6:5e:cb:08:2a:5e:30:f2:2d:66:c7:84:
+ 1b:64:57:38:9d:75:2d:56:c6:2f:61:ef:96:fc:20:
+ 46:bd:eb:d4:7b:3f:3f:7c:47:38:04:a9:1b:aa:52:
+ df:13:37:d3:15:15:4e:bd:5f:7c:af:ad:63:c7:79:
+ dc:08:7b:d5:a0:e5:f7:5b:75:ac:80:55:99:92:61:
+ 9b:cd:2a:17:7d:db:8f:f4:b5:6a:ea:17:4a:64:28:
+ 66:15:29:6c:02:f1:6b:d5:ba:a3:33:dc:5a:67:a7:
+ 05:e2:bf:65:b6:16:b0:10:ed:cd:50:33:c9:70:50:
+ ec:19:8e:b0:c7:f2:74:5b:6b:44:c6:7d:96:b9:98:
+ 08:59:66:de:29:01:9b:f4:2a:6d:d3:15:3a:90:6a:
+ 67:f1:b4:6b:66:d9:21:eb:ca:d9:62:7c:46:10:5c:
+ de:75:49:67:9e:42:f9:fe:75:a9:a3:ad:ff:76:0a:
+ 67:40:e3:c5:f7:8d:c7:85:9a:59:9e:62:9a:6a:ed:
+ 45:87:98:67:b2:d5:4a:3c:d7:b4:3b:00:0d:c0:8f:
+ 1f:e1:40:c4:ae:6c:21:dc:49:7e:7e:ca:b2:8d:6d:
+ b6:bf:93:2f:a1:5c:3e:8f:ca:ed:80:8e:58:e1:db:
+ 57:cf:85:36:38:b2:71:a4:09:8c:92:89:08:88:48:
+ f1:40:63:18:b2:5b:8c:5a:e3:c3:d3:17:aa:ab:19:
+ a3:2c:1b:e4:d5:c6:e2:66:7a:d7:82:19:a6:3b:16:
+ 2c:2f:71:87:5f:45:9e:95:73:93:c2:42:81:21:13:
+ 96:d7:9d:bb:93:68:15:fa:9d:a4:1d:8c:f2:81:e0:
+ 58:06:bd:c9:b6:e3:f6:89:5d:89:f9:ac:44:a1:cb:
+ 6b:fa:16:f1:c7:50:3d:24:da:f7:c3:e4:87:d5:56:
+ f1:4f:90:30:fa:45:09:59:da:34:ce:e0:13:1c:04:
+ 7c:00:d4:9b:86:a4:40:bc:d9:dc:4c:57:7e:ae:b7:
+ 33:b6:5e:76:e1:65:8b:66:df:8d:ca:d7:98:af:ce:
+ 36:98:8c:9c:83:99:03:70:f3:af:74:ed:c6:0e:36:
+ e7:bd:ec:c1:73:a7:94:5a:cb:92:64:82:a6:00:c1:
+ 70:a1:6e:2c:29:e1:58:57:ec:5a:7c:99:6b:25:a4:
+ 90:3a:80:f4:20:9d:9a:ce:c7:2d:f9:b2:4b:29:95:
+ 83:e9:35:8d:a7:49:48:a7:0f:4c:19:91:d0:f5:bf:
+ 10:e0:71
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Subject Key Identifier:
+ 74:49:99:D1:FF:B4:7A:68:45:75:C3:7E:B4:DC:CC:CE:39:33:DA:08
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ Signature Algorithm: sha384WithRSAEncryption
+ Signature Value:
+ 23:43:53:24:62:5c:6d:fd:3e:c2:cf:55:00:6c:c5:56:88:b9:
+ 0e:dd:3a:e2:25:0d:95:4a:97:ca:80:89:ee:2a:cd:65:f8:db:
+ 16:e0:09:92:e0:18:c7:78:98:bb:f3:ec:42:52:fb:a9:a4:82:
+ d7:4d:d8:8a:fc:e4:4e:fd:ab:90:c4:38:75:32:84:9f:ff:b3:
+ b0:2b:02:33:36:c0:10:90:6f:1d:9c:af:e1:69:93:ec:a3:45:
+ 2f:14:9f:f5:4c:2a:65:43:72:0c:f7:c3:f8:95:8b:14:f3:85:
+ 20:62:dd:54:53:dd:2c:dc:18:95:69:4f:83:47:70:40:33:58:
+ 77:12:0c:a2:eb:52:31:1e:4c:c9:a8:ce:c5:ef:c3:d1:ad:e0:
+ 6b:03:00:34:26:b4:54:21:35:97:01:dc:5f:1b:f1:7c:e7:55:
+ fa:2d:68:77:7b:d3:69:cc:d3:0e:6b:ba:4d:76:44:d6:c2:15:
+ 9a:26:ec:b0:c5:f5:bb:d1:7a:74:c2:6c:cd:c5:b5:5e:f6:4c:
+ e6:5b:2d:81:db:b3:b7:3a:97:9e:ed:cf:46:b2:50:3d:84:60:
+ 99:71:b5:33:b5:57:45:e6:42:47:75:6a:0e:b0:08:0c:ae:bd:
+ de:f7:bb:0f:58:3d:8f:03:31:e8:3d:82:50:ca:2f:5e:0c:5d:
+ b4:97:be:20:34:07:f4:c4:12:e1:ee:d7:b0:d9:59:2d:69:f7:
+ 31:04:f4:f2:f9:ab:f9:13:31:f8:01:77:0e:3d:42:23:26:cc:
+ 9a:72:67:51:21:7a:cc:3c:85:a8:ea:21:6a:3b:db:5a:3c:a5:
+ 34:9e:9a:c0:2c:df:80:9c:29:e0:df:77:94:d1:a2:80:42:ff:
+ 6a:4c:5b:11:d0:f5:cd:a2:be:ae:cc:51:5c:c3:d5:54:7b:0c:
+ ae:d6:b9:06:77:80:e2:ef:07:1a:68:cc:59:51:ad:7e:5c:67:
+ 6b:b9:db:e2:07:42:5b:b8:01:05:58:39:4d:e4:bb:98:a3:b1:
+ 32:ec:d9:a3:d6:6f:94:23:ff:3b:b7:29:65:e6:07:e9:ef:b6:
+ 19:ea:e7:c2:38:1d:32:88:90:3c:13:2b:6e:cc:ef:ab:77:06:
+ 34:77:84:4f:72:e4:81:84:f9:b9:74:34:de:76:4f:92:2a:53:
+ b1:25:39:db:3c:ff:e5:3e:a6:0e:e5:6b:9e:ff:db:ec:2f:74:
+ 83:df:8e:b4:b3:a9:de:14:4d:ff:31:a3:45:73:24:fa:95:29:
+ cc:12:97:04:a2:38:b6:8d:b0:f0:37:fc:c8:21:7f:3f:b3:24:
+ 1b:3d:8b:6e:cc:4d:b0:16:0d:96:1d:83:1f:46:c0:9b:bd:43:
+ 99:e7:c4:96:2e:ce:5f:c9
+SHA1 Fingerprint=18:52:3B:0D:06:37:E4:D6:3A:DF:23:E4:98:FB:5B:16:FB:86:74:48
diff --git a/apex/ca-certificates/files/2c63f966.0 b/apex/ca-certificates/files/2c63f966.0
new file mode 100644
index 0000000..3f313b5
--- /dev/null
+++ b/apex/ca-certificates/files/2c63f966.0
@@ -0,0 +1,124 @@
+-----BEGIN CERTIFICATE-----
+MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBO
+MQswCQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQD
+DBxTU0wuY29tIFRMUyBSU0EgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloX
+DTQ2MDgxOTE2MzQyMVowTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jw
+b3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgUlNBIFJvb3QgQ0EgMjAyMjCC
+AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANCkCXJPQIgSYT41I57u9nTP
+L3tYPc48DRAokC+X94xI2KDYJbFMsBFMF3NQ0CJKY7uB0ylu1bUJPiYYf7ISf5OY
+t6/wNr/y7hienDtSxUcZXXTzZGbVXcdotL8bHAajvI9AI7YexoS9UcQbOcGV0ins
+S657Lb85/bRi3pZ7QcacoOAGcvvwB5cJOYF0r/c0WRFXCsJbwST0MXMwgsadugL3
+PnxEX4MN8/HdIGkWCVDi1FW24IBydm5MR7d1VVm0U3TZlMZBrViKMWYPHqIbKUBO
+L9975hYsLfy/7PO0+r4Y9ptJ1O4Fbtk085zx7AGL0SDGD6C1vBdOSHtRwvzpXGk3
+R2azaPgVKPC506QVzFpPulJwoxJF3ca6TvvC0PeoUidtbnm1jPx7jMEWTO6Af77w
+dr5BUxIzrlo4QqvXDz5BjXYHMtWrifZOZ9mxQnUjbvPNQrL8VfVThxc7wDNY8VLS
++YCk8OjwO4s4zKTGkH8PnP2L0aPP2oOnaclQNtVcBdIKQXTbYxE3waWglksejBYS
+d66UNHsef8JmAOSqg+qKkK3ONkRN0VHpvB/zagX9wHQfJRlAUW7qglFA35u5CCoG
+AtUjHBPW6dvbxrB6y3snm/vg1UYk7RBLY0ulBY+6uB0rpvqR4pJSvezrZ5dtmi2f
+gTIFZzL7SAg/2SW4BCUvAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j
+BBgwFoAU+y437uOEeicuzRk1sTN8/9REQrkwHQYDVR0OBBYEFPsuN+7jhHonLs0Z
+NbEzfP/UREK5MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAjYlt
+hEUY8U+zoO9opMAdrDC8Z2awms22qyIZZtM7QbUQnRC6cm4pJCAcAZli05bg4vsM
+QtfhWsSWTVTNj8pDU/0quOr4ZcoBwq1gaAafORpR2eCNJvkLTqVTJXojpBzOCBvf
+R4iyrT7gJ4eLSYwfqUdYe5byiB0YrrPRpgqU+tvT5TgKa3kSM/tKWTcWQA673vWJ
+DPFs0/dRa1419dvAJuoSc06pkZCmF8NsLzjUo3KUQyxi4U5cMj29TH0ZR6LDSeeW
+P4+a0zvkEdiLA9z2tmBVGKaBUfPhqBVq6+AL8BQx1rmMRTqoENjwuSfr98t67wVy
+lrXEj5ZzxOhWc5y8aVFjvO9nHEMaX3cZHxj4HCUp+UmZKbaSPaKDN7EgkaibMOlq
+bLQjk2UEqxHzDh1TJElTHaE/nUiSEeJ9DU/1172iWD54nR4fK/4huxoTtrEoZP2w
+AgDHbICivRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3q
+r5nsLFR+jM4uElZI7xc7P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sji
+Mho6/4UIyYOf8kpIEFR3N+2ivEC+5BB09+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU
+98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA=
+-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 6f:be:da:ad:73:bd:08:40:e2:8b:4d:be:d4:f7:5b:91
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=SSL Corporation, CN=SSL.com TLS RSA Root CA 2022
+ Validity
+ Not Before: Aug 25 16:34:22 2022 GMT
+ Not After : Aug 19 16:34:21 2046 GMT
+ Subject: C=US, O=SSL Corporation, CN=SSL.com TLS RSA Root CA 2022
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (4096 bit)
+ Modulus:
+ 00:d0:a4:09:72:4f:40:88:12:61:3e:35:23:9e:ee:
+ f6:74:cf:2f:7b:58:3d:ce:3c:0d:10:28:90:2f:97:
+ f7:8c:48:d8:a0:d8:25:b1:4c:b0:11:4c:17:73:50:
+ d0:22:4a:63:bb:81:d3:29:6e:d5:b5:09:3e:26:18:
+ 7f:b2:12:7f:93:98:b7:af:f0:36:bf:f2:ee:18:9e:
+ 9c:3b:52:c5:47:19:5d:74:f3:64:66:d5:5d:c7:68:
+ b4:bf:1b:1c:06:a3:bc:8f:40:23:b6:1e:c6:84:bd:
+ 51:c4:1b:39:c1:95:d2:29:ec:4b:ae:7b:2d:bf:39:
+ fd:b4:62:de:96:7b:41:c6:9c:a0:e0:06:72:fb:f0:
+ 07:97:09:39:81:74:af:f7:34:59:11:57:0a:c2:5b:
+ c1:24:f4:31:73:30:82:c6:9d:ba:02:f7:3e:7c:44:
+ 5f:83:0d:f3:f1:dd:20:69:16:09:50:e2:d4:55:b6:
+ e0:80:72:76:6e:4c:47:b7:75:55:59:b4:53:74:d9:
+ 94:c6:41:ad:58:8a:31:66:0f:1e:a2:1b:29:40:4e:
+ 2f:df:7b:e6:16:2c:2d:fc:bf:ec:f3:b4:fa:be:18:
+ f6:9b:49:d4:ee:05:6e:d9:34:f3:9c:f1:ec:01:8b:
+ d1:20:c6:0f:a0:b5:bc:17:4e:48:7b:51:c2:fc:e9:
+ 5c:69:37:47:66:b3:68:f8:15:28:f0:b9:d3:a4:15:
+ cc:5a:4f:ba:52:70:a3:12:45:dd:c6:ba:4e:fb:c2:
+ d0:f7:a8:52:27:6d:6e:79:b5:8c:fc:7b:8c:c1:16:
+ 4c:ee:80:7f:be:f0:76:be:41:53:12:33:ae:5a:38:
+ 42:ab:d7:0f:3e:41:8d:76:07:32:d5:ab:89:f6:4e:
+ 67:d9:b1:42:75:23:6e:f3:cd:42:b2:fc:55:f5:53:
+ 87:17:3b:c0:33:58:f1:52:d2:f9:80:a4:f0:e8:f0:
+ 3b:8b:38:cc:a4:c6:90:7f:0f:9c:fd:8b:d1:a3:cf:
+ da:83:a7:69:c9:50:36:d5:5c:05:d2:0a:41:74:db:
+ 63:11:37:c1:a5:a0:96:4b:1e:8c:16:12:77:ae:94:
+ 34:7b:1e:7f:c2:66:00:e4:aa:83:ea:8a:90:ad:ce:
+ 36:44:4d:d1:51:e9:bc:1f:f3:6a:05:fd:c0:74:1f:
+ 25:19:40:51:6e:ea:82:51:40:df:9b:b9:08:2a:06:
+ 02:d5:23:1c:13:d6:e9:db:db:c6:b0:7a:cb:7b:27:
+ 9b:fb:e0:d5:46:24:ed:10:4b:63:4b:a5:05:8f:ba:
+ b8:1d:2b:a6:fa:91:e2:92:52:bd:ec:eb:67:97:6d:
+ 9a:2d:9f:81:32:05:67:32:fb:48:08:3f:d9:25:b8:
+ 04:25:2f
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Authority Key Identifier:
+ FB:2E:37:EE:E3:84:7A:27:2E:CD:19:35:B1:33:7C:FF:D4:44:42:B9
+ X509v3 Subject Key Identifier:
+ FB:2E:37:EE:E3:84:7A:27:2E:CD:19:35:B1:33:7C:FF:D4:44:42:B9
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ Signature Algorithm: sha256WithRSAEncryption
+ Signature Value:
+ 8d:89:6d:84:45:18:f1:4f:b3:a0:ef:68:a4:c0:1d:ac:30:bc:
+ 67:66:b0:9a:cd:b6:ab:22:19:66:d3:3b:41:b5:10:9d:10:ba:
+ 72:6e:29:24:20:1c:01:99:62:d3:96:e0:e2:fb:0c:42:d7:e1:
+ 5a:c4:96:4d:54:cd:8f:ca:43:53:fd:2a:b8:ea:f8:65:ca:01:
+ c2:ad:60:68:06:9f:39:1a:51:d9:e0:8d:26:f9:0b:4e:a5:53:
+ 25:7a:23:a4:1c:ce:08:1b:df:47:88:b2:ad:3e:e0:27:87:8b:
+ 49:8c:1f:a9:47:58:7b:96:f2:88:1d:18:ae:b3:d1:a6:0a:94:
+ fa:db:d3:e5:38:0a:6b:79:12:33:fb:4a:59:37:16:40:0e:bb:
+ de:f5:89:0c:f1:6c:d3:f7:51:6b:5e:35:f5:db:c0:26:ea:12:
+ 73:4e:a9:91:90:a6:17:c3:6c:2f:38:d4:a3:72:94:43:2c:62:
+ e1:4e:5c:32:3d:bd:4c:7d:19:47:a2:c3:49:e7:96:3f:8f:9a:
+ d3:3b:e4:11:d8:8b:03:dc:f6:b6:60:55:18:a6:81:51:f3:e1:
+ a8:15:6a:eb:e0:0b:f0:14:31:d6:b9:8c:45:3a:a8:10:d8:f0:
+ b9:27:eb:f7:cb:7a:ef:05:72:96:b5:c4:8f:96:73:c4:e8:56:
+ 73:9c:bc:69:51:63:bc:ef:67:1c:43:1a:5f:77:19:1f:18:f8:
+ 1c:25:29:f9:49:99:29:b6:92:3d:a2:83:37:b1:20:91:a8:9b:
+ 30:e9:6a:6c:b4:23:93:65:04:ab:11:f3:0e:1d:53:24:49:53:
+ 1d:a1:3f:9d:48:92:11:e2:7d:0d:4f:f5:d7:bd:a2:58:3e:78:
+ 9d:1e:1f:2b:fe:21:bb:1a:13:b6:b1:28:64:fd:b0:02:00:c7:
+ 6c:80:a2:bd:16:50:20:0f:72:81:5f:cc:94:ff:bb:99:e6:ba:
+ 90:cb:ea:f9:c6:0c:c2:ae:c5:19:ce:33:a1:6b:5c:bb:7e:7c:
+ 34:57:17:ad:f0:3f:ae:cd:ea:af:99:ec:2c:54:7e:8c:ce:2e:
+ 12:56:48:ef:17:3b:3f:4a:5e:60:d2:dc:74:36:bc:a5:43:63:
+ cb:0f:5b:a3:02:56:09:9e:24:2c:e1:86:81:8c:fe:ab:17:2c:
+ fa:c8:e2:32:1a:3a:ff:85:08:c9:83:9f:f2:4a:48:10:54:77:
+ 37:ed:a2:bc:40:be:e4:10:74:f7:e4:5b:bb:b9:f3:89:f9:8f:
+ 41:d8:c7:e4:50:90:35:80:3e:1c:b8:4d:90:d3:d4:f7:c3:b0:
+ a1:7e:84:ca:77:92:31:2c:b8:90:b1:82:7a:74:4e:9b:13:26:
+ b4:d5:50:66:54:78:ae:60
+SHA1 Fingerprint=EC:2C:83:40:72:AF:26:95:10:FF:0E:F2:03:EE:31:70:F6:78:9D:CA
diff --git a/apex/ca-certificates/files/2d21b73c.0 b/apex/ca-certificates/files/2d21b73c.0
new file mode 100644
index 0000000..e5121cf
--- /dev/null
+++ b/apex/ca-certificates/files/2d21b73c.0
@@ -0,0 +1,54 @@
+-----BEGIN CERTIFICATE-----
+MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4w
+LAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0w
+CwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0
+MTcwOTI2MjJaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBF
+Q0MgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMHYwEAYHKoZI
+zj0CAQYFK4EEACIDYgAEloZYKDcKZ9Cg3iQZGeHkBQcfl+3oZIK59sRxUM6KDP/X
+tXa7oWyTbIOiaG6l2b4siJVBzV3dscqDY4PMwL502eCdpO5KTlbgmClBk1IQ1SQ4
+AjJn8ZQSb+/Xxd4u/RmAo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR2
+KCXWfeBmmnoJsmo7jjPXNtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMD
+aAAwZQIwW5kp85wxtolrbNa9d+F851F+uDrNozZffPc8dz7kUK2o59JZDCaOMDtu
+CCrCp1rIAjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGYa3cpetskz2VAv9LcjBHo
+9H1/IISpQuQo
+-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 3d:98:3b:a6:66:3d:90:63:f7:7e:26:57:38:04:ef:00
+ Signature Algorithm: ecdsa-with-SHA384
+ Issuer: CN=Atos TrustedRoot Root CA ECC TLS 2021, O=Atos, C=DE
+ Validity
+ Not Before: Apr 22 09:26:23 2021 GMT
+ Not After : Apr 17 09:26:22 2041 GMT
+ Subject: CN=Atos TrustedRoot Root CA ECC TLS 2021, O=Atos, C=DE
+ Subject Public Key Info:
+ Public Key Algorithm: id-ecPublicKey
+ Public-Key: (384 bit)
+ pub:
+ 04:96:86:58:28:37:0a:67:d0:a0:de:24:19:19:e1:
+ e4:05:07:1f:97:ed:e8:64:82:b9:f6:c4:71:50:ce:
+ 8a:0c:ff:d7:b5:76:bb:a1:6c:93:6c:83:a2:68:6e:
+ a5:d9:be:2c:88:95:41:cd:5d:dd:b1:ca:83:63:83:
+ cc:c0:be:74:d9:e0:9d:a4:ee:4a:4e:56:e0:98:29:
+ 41:93:52:10:d5:24:38:02:32:67:f1:94:12:6f:ef:
+ d7:c5:de:2e:fd:19:80
+ ASN1 OID: secp384r1
+ NIST CURVE: P-384
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Subject Key Identifier:
+ 76:28:25:D6:7D:E0:66:9A:7A:09:B2:6A:3B:8E:33:D7:36:D3:4F:A2
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ Signature Algorithm: ecdsa-with-SHA384
+ Signature Value:
+ 30:65:02:30:5b:99:29:f3:9c:31:b6:89:6b:6c:d6:bd:77:e1:
+ 7c:e7:51:7e:b8:3a:cd:a3:36:5f:7c:f7:3c:77:3e:e4:50:ad:
+ a8:e7:d2:59:0c:26:8e:30:3b:6e:08:2a:c2:a7:5a:c8:02:31:
+ 00:99:e3:0c:e7:a3:c3:af:d3:49:2e:46:82:23:66:5d:c9:00:
+ 14:12:fd:38:f4:e1:98:6b:77:29:7a:db:24:cf:65:40:bf:d2:
+ dc:8c:11:e8:f4:7d:7f:20:84:a9:42:e4:28
+SHA1 Fingerprint=9E:BC:75:10:42:B3:02:F3:81:F4:F7:30:62:D4:8F:C3:A7:51:B2:DD
diff --git a/apex/ca-certificates/files/34d996fb.0 b/apex/ca-certificates/files/34d996fb.0
new file mode 100644
index 0000000..7ac8538
--- /dev/null
+++ b/apex/ca-certificates/files/34d996fb.0
@@ -0,0 +1,54 @@
+-----BEGIN CERTIFICATE-----
+MIICHDCCAaOgAwIBAgIUKP2ZYEFHpgE6yhR7H+/5aAiDXX0wCgYIKoZIzj0EAwMw
+TjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29t
+bVNjb3BlIFB1YmxpYyBUcnVzdCBFQ0MgUm9vdC0wMjAeFw0yMTA0MjgxNzQ0NTRa
+Fw00NjA0MjgxNzQ0NTNaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21tU2Nv
+cGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgRUNDIFJvb3QtMDIw
+djAQBgcqhkjOPQIBBgUrgQQAIgNiAAR4MIHoYx7l63FRD/cHB8o5mXxO1Q/MMDAL
+j2aTPs+9xYa9+bG3tD60B8jzljHz7aRP+KNOjSkVWLjVb3/ubCK1sK9IRQq9qEmU
+v4RDsNuESgMjGWdqb8FuvAY5N9GIIvejQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD
+VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTmGHX/72DehKT1RsfeSlXjMjZ59TAKBggq
+hkjOPQQDAwNnADBkAjAmc0l6tqvmSfR9Uj/UQQSugEODZXW5hYA4O9Zv5JOGq4/n
+ich/m35rChJVYaoR4HkCMHfoMXGsPHED1oQmHhS48zs73u1Z/GtMMH9ZzkXpc2AV
+mkzw5l4lIhVtwodZ0LKOag==
+-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 28:fd:99:60:41:47:a6:01:3a:ca:14:7b:1f:ef:f9:68:08:83:5d:7d
+ Signature Algorithm: ecdsa-with-SHA384
+ Issuer: C=US, O=CommScope, CN=CommScope Public Trust ECC Root-02
+ Validity
+ Not Before: Apr 28 17:44:54 2021 GMT
+ Not After : Apr 28 17:44:53 2046 GMT
+ Subject: C=US, O=CommScope, CN=CommScope Public Trust ECC Root-02
+ Subject Public Key Info:
+ Public Key Algorithm: id-ecPublicKey
+ Public-Key: (384 bit)
+ pub:
+ 04:78:30:81:e8:63:1e:e5:eb:71:51:0f:f7:07:07:
+ ca:39:99:7c:4e:d5:0f:cc:30:30:0b:8f:66:93:3e:
+ cf:bd:c5:86:bd:f9:b1:b7:b4:3e:b4:07:c8:f3:96:
+ 31:f3:ed:a4:4f:f8:a3:4e:8d:29:15:58:b8:d5:6f:
+ 7f:ee:6c:22:b5:b0:af:48:45:0a:bd:a8:49:94:bf:
+ 84:43:b0:db:84:4a:03:23:19:67:6a:6f:c1:6e:bc:
+ 06:39:37:d1:88:22:f7
+ ASN1 OID: secp384r1
+ NIST CURVE: P-384
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ E6:18:75:FF:EF:60:DE:84:A4:F5:46:C7:DE:4A:55:E3:32:36:79:F5
+ Signature Algorithm: ecdsa-with-SHA384
+ Signature Value:
+ 30:64:02:30:26:73:49:7a:b6:ab:e6:49:f4:7d:52:3f:d4:41:
+ 04:ae:80:43:83:65:75:b9:85:80:38:3b:d6:6f:e4:93:86:ab:
+ 8f:e7:89:c8:7f:9b:7e:6b:0a:12:55:61:aa:11:e0:79:02:30:
+ 77:e8:31:71:ac:3c:71:03:d6:84:26:1e:14:b8:f3:3b:3b:de:
+ ed:59:fc:6b:4c:30:7f:59:ce:45:e9:73:60:15:9a:4c:f0:e6:
+ 5e:25:22:15:6d:c2:87:59:d0:b2:8e:6a
+SHA1 Fingerprint=3C:3F:EF:57:0F:FE:65:93:86:9E:A0:FE:B0:F6:ED:8E:D1:13:C7:E5
diff --git a/apex/ca-certificates/files/3afde786.0 b/apex/ca-certificates/files/3afde786.0
new file mode 100644
index 0000000..786b1ca
--- /dev/null
+++ b/apex/ca-certificates/files/3afde786.0
@@ -0,0 +1,54 @@
+-----BEGIN CERTIFICATE-----
+MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQsw
+CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T
+ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcN
+MjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYG
+A1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT
+ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA
+IgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccC
+WvkEN/U0NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+
+6xnOQ6OjQjBAMB0GA1UdDgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8B
+Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjAn7qRa
+qCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RHlAFWovgzJQxC36oCMB3q
+4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21USAGKcw==
+-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 42:f2:cc:da:1b:69:37:44:5f:15:fe:75:28:10:b8:f4
+ Signature Algorithm: ecdsa-with-SHA384
+ Issuer: C=GB, O=Sectigo Limited, CN=Sectigo Public Server Authentication Root E46
+ Validity
+ Not Before: Mar 22 00:00:00 2021 GMT
+ Not After : Mar 21 23:59:59 2046 GMT
+ Subject: C=GB, O=Sectigo Limited, CN=Sectigo Public Server Authentication Root E46
+ Subject Public Key Info:
+ Public Key Algorithm: id-ecPublicKey
+ Public-Key: (384 bit)
+ pub:
+ 04:76:fa:99:a9:6e:20:ed:f9:d7:77:e3:07:3b:a8:
+ db:3d:5f:38:e8:ab:55:a6:56:4f:d6:48:ea:ec:7f:
+ 2d:aa:c3:b2:c5:79:ec:99:61:7f:10:79:c7:02:5a:
+ f9:04:37:f5:34:35:2b:77:ce:7f:20:8f:52:a3:00:
+ 89:ec:d5:a7:a2:6d:5b:e3:4b:92:93:a0:80:f5:01:
+ 94:dc:f0:68:07:1e:cd:ee:fe:25:52:b5:20:43:1c:
+ 1b:fe:eb:19:ce:43:a3
+ ASN1 OID: secp384r1
+ NIST CURVE: P-384
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ D1:22:DA:4C:59:F1:4B:5F:26:38:AA:9D:D6:EE:EB:0D:C3:FB:A9:61
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ Signature Algorithm: ecdsa-with-SHA384
+ Signature Value:
+ 30:64:02:30:27:ee:a4:5a:a8:21:bb:e9:47:97:94:89:a5:74:
+ 20:6d:79:4f:c8:bd:93:5e:58:18:fb:2d:1a:00:6a:c9:b8:3d:
+ d0:a4:4f:44:47:94:01:56:a2:f8:33:25:0c:42:df:aa:02:30:
+ 1d:ea:e1:2e:88:2e:e1:f9:a7:1d:02:32:4e:f2:9f:6c:55:74:
+ e3:ae:ae:fb:a5:1a:ee:ed:d2:fc:c2:03:11:eb:45:5c:60:10:
+ 3d:5c:7f:99:03:5b:6d:54:48:01:8a:73
+SHA1 Fingerprint=EC:8A:39:6C:40:F0:2E:BC:42:75:D4:9F:AB:1C:1A:5B:67:BE:D2:9A
diff --git a/apex/ca-certificates/files/595e996b.0 b/apex/ca-certificates/files/595e996b.0
new file mode 100644
index 0000000..6ff5775
--- /dev/null
+++ b/apex/ca-certificates/files/595e996b.0
@@ -0,0 +1,54 @@
+-----BEGIN CERTIFICATE-----
+MIICHTCCAaOgAwIBAgIUQ3CCd89NXTTxyq4yLzf39H91oJ4wCgYIKoZIzj0EAwMw
+TjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29t
+bVNjb3BlIFB1YmxpYyBUcnVzdCBFQ0MgUm9vdC0wMTAeFw0yMTA0MjgxNzM1NDNa
+Fw00NjA0MjgxNzM1NDJaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21tU2Nv
+cGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgRUNDIFJvb3QtMDEw
+djAQBgcqhkjOPQIBBgUrgQQAIgNiAARLNumuV16ocNfQj3Rid8NeeqrltqLxeP0C
+flfdkXmcbLlSiFS8LwS+uM32ENEp7LXQoMPwiXAZu1FlxUOcw5tjnSCDPgYLpkJE
+hRGnSjot6dZoL0hOUysHP029uax3OVejQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD
+VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSOB2LAUN3GGQYARnQE9/OufXVNMDAKBggq
+hkjOPQQDAwNoADBlAjEAnDPfQeMjqEI2Jpc1XHvr20v4qotzVRVcrHgpD7oh2MSg
+2NED3W3ROT3Ek2DS43KyAjB8xX6I01D1HiXo+k515liWpDVfG2XqYZpwI7UNo5uS
+Um9poIyNStDuiw7LR47QjRE=
+-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 43:70:82:77:cf:4d:5d:34:f1:ca:ae:32:2f:37:f7:f4:7f:75:a0:9e
+ Signature Algorithm: ecdsa-with-SHA384
+ Issuer: C=US, O=CommScope, CN=CommScope Public Trust ECC Root-01
+ Validity
+ Not Before: Apr 28 17:35:43 2021 GMT
+ Not After : Apr 28 17:35:42 2046 GMT
+ Subject: C=US, O=CommScope, CN=CommScope Public Trust ECC Root-01
+ Subject Public Key Info:
+ Public Key Algorithm: id-ecPublicKey
+ Public-Key: (384 bit)
+ pub:
+ 04:4b:36:e9:ae:57:5e:a8:70:d7:d0:8f:74:62:77:
+ c3:5e:7a:aa:e5:b6:a2:f1:78:fd:02:7e:57:dd:91:
+ 79:9c:6c:b9:52:88:54:bc:2f:04:be:b8:cd:f6:10:
+ d1:29:ec:b5:d0:a0:c3:f0:89:70:19:bb:51:65:c5:
+ 43:9c:c3:9b:63:9d:20:83:3e:06:0b:a6:42:44:85:
+ 11:a7:4a:3a:2d:e9:d6:68:2f:48:4e:53:2b:07:3f:
+ 4d:bd:b9:ac:77:39:57
+ ASN1 OID: secp384r1
+ NIST CURVE: P-384
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ 8E:07:62:C0:50:DD:C6:19:06:00:46:74:04:F7:F3:AE:7D:75:4D:30
+ Signature Algorithm: ecdsa-with-SHA384
+ Signature Value:
+ 30:65:02:31:00:9c:33:df:41:e3:23:a8:42:36:26:97:35:5c:
+ 7b:eb:db:4b:f8:aa:8b:73:55:15:5c:ac:78:29:0f:ba:21:d8:
+ c4:a0:d8:d1:03:dd:6d:d1:39:3d:c4:93:60:d2:e3:72:b2:02:
+ 30:7c:c5:7e:88:d3:50:f5:1e:25:e8:fa:4e:75:e6:58:96:a4:
+ 35:5f:1b:65:ea:61:9a:70:23:b5:0d:a3:9b:92:52:6f:69:a0:
+ 8c:8d:4a:d0:ee:8b:0e:cb:47:8e:d0:8d:11
+SHA1 Fingerprint=07:86:C0:D8:DD:8E:C0:80:98:06:98:D0:58:7A:EF:DE:A6:CC:A2:5D
diff --git a/apex/ca-certificates/files/8d10a21f.0 b/apex/ca-certificates/files/8d10a21f.0
new file mode 100644
index 0000000..d0d08f1
--- /dev/null
+++ b/apex/ca-certificates/files/8d10a21f.0
@@ -0,0 +1,121 @@
+-----BEGIN CERTIFICATE-----
+MIIFbDCCA1SgAwIBAgIUPgNJgXUWdDGOTKvVxZAplsU5EN0wDQYJKoZIhvcNAQEL
+BQAwTjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwi
+Q29tbVNjb3BlIFB1YmxpYyBUcnVzdCBSU0EgUm9vdC0wMTAeFw0yMTA0MjgxNjQ1
+NTRaFw00NjA0MjgxNjQ1NTNaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21t
+U2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgUlNBIFJvb3Qt
+MDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwSGWjDR1C45FtnYSk
+YZYSwu3D2iM0GXb26v1VWvZVAVMP8syMl0+5UMuzAURWlv2bKOx7dAvnQmtVzslh
+suitQDy6uUEKBU8bJoWPQ7VAtYXR1HHcg0Hz9kXHgKKEUJdGzqAMxGBWBB0HW0al
+DrJLpA6lfO741GIDuZNqihS4cPgugkY4Iw50x2tBt9Apo52AsH53k2NC+zSDO3Oj
+WiE260f6GBfZumbCk6SP/F2krfxQapWsvCQz0b2If4b19bJzKo98rwjyGpg/qYFl
+P8GMicWWMJoKz/TUyDTtnS+8jTiGU+6Xn6myY5QXjQ/cZip8UlF1y5mO6D1cv547
+KI2DAg+pn3LiLCuz3GaXAEDQpFSOm117RTYm1nJD68/A6g3czhLmfTifBSeolz7p
+UcZsBSjBAg/pGG3svZwG1KdJ9FQFa2ww8esD1eo9anbCyxooSU1/ZOD6K9pzg4H/
+kQO9lLvkuI6cMmPNn7togbGEW682v3fuHX/3SZtS7NJ3Wn2RnU3COS3kuoL4b/JO
+Hg9O5j9ZpSPcPYeoKFgo0fEbNttPxP/hjFtyjMcmAyejOQoBqsCyMWCDIqFPEgkB
+Ea801M/XrmLTBQe0MXXgDW1XT2mH+VepuhX2yFJtocucH+X8eKg1mp9BFM6ltM6U
+CBwJrVbl2rZJmkrqYxhTnCwuwwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G
+A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUN12mmnQywsL5x6YVEFm45P3luG0wDQYJ
+KoZIhvcNAQELBQADggIBAK+nz97/4L1CjU3lIpbfaOp9TSp90K09FlxD533Ahuh6
+NWPxzIHIxgvoLlI1pKZJkGNRrDSsBTtXAOnTYtPZKdVUvhwQkZyybf5Z/Xn36lbQ
+nmhUQo8mUuJM3y+Xpi/SB5io82BdS5pYV4jvguX6r2yBS5KPQJqTRlnLX3gWsWc+
+QgvfKNmwrZggvkN80V4aCRckjXtdlemrwWCrWxhkgPut4AZ9HcpZuPN4KWfGVh2v
+trV0KnahP/t1MJ+UXjulYPPLXAziDslg+MkfFoom3ecnf+slpoq9uC02EJqxWE2a
+aE9gVOX2RhOOiKy8IUISrcZKiX2bwdgt6ZYD9KJ0DLwAHb/WNyVntHKLr4W96ioD
+j8z7PEQkguIBpQtZtjSNMgsSDesnwv1B10A8ckYpwIzqug/xBpMu95yo9GA+o/E4
+Xo4TwbM6l4c/ksp4qRyv0LAbJh6+cOx69TOY6lz/KwsETkPdY34Op054A5U+1C0w
+lREQKC6/oAI+/15Z0wUOlV9TRe9rh9VIzRamloPh37MG88EU26fsHItdkJANclHn
+YfkUyq+Dj7+vsQpZXdxc1+SWrVtgHdqul7I52Qb1dgAT+GhMIbA1xNxVssnBQVoc
+icCMb3SgazNNtQEo/a2tiRc7ppqEvOuM6sRxJKi6KfkIsidWNTJf6jn7MZrVGczw
+-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 3e:03:49:81:75:16:74:31:8e:4c:ab:d5:c5:90:29:96:c5:39:10:dd
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=CommScope, CN=CommScope Public Trust RSA Root-01
+ Validity
+ Not Before: Apr 28 16:45:54 2021 GMT
+ Not After : Apr 28 16:45:53 2046 GMT
+ Subject: C=US, O=CommScope, CN=CommScope Public Trust RSA Root-01
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (4096 bit)
+ Modulus:
+ 00:b0:48:65:a3:0d:1d:42:e3:91:6d:9d:84:a4:61:
+ 96:12:c2:ed:c3:da:23:34:19:76:f6:ea:fd:55:5a:
+ f6:55:01:53:0f:f2:cc:8c:97:4f:b9:50:cb:b3:01:
+ 44:56:96:fd:9b:28:ec:7b:74:0b:e7:42:6b:55:ce:
+ c9:61:b2:e8:ad:40:3c:ba:b9:41:0a:05:4f:1b:26:
+ 85:8f:43:b5:40:b5:85:d1:d4:71:dc:83:41:f3:f6:
+ 45:c7:80:a2:84:50:97:46:ce:a0:0c:c4:60:56:04:
+ 1d:07:5b:46:a5:0e:b2:4b:a4:0e:a5:7c:ee:f8:d4:
+ 62:03:b9:93:6a:8a:14:b8:70:f8:2e:82:46:38:23:
+ 0e:74:c7:6b:41:b7:d0:29:a3:9d:80:b0:7e:77:93:
+ 63:42:fb:34:83:3b:73:a3:5a:21:36:eb:47:fa:18:
+ 17:d9:ba:66:c2:93:a4:8f:fc:5d:a4:ad:fc:50:6a:
+ 95:ac:bc:24:33:d1:bd:88:7f:86:f5:f5:b2:73:2a:
+ 8f:7c:af:08:f2:1a:98:3f:a9:81:65:3f:c1:8c:89:
+ c5:96:30:9a:0a:cf:f4:d4:c8:34:ed:9d:2f:bc:8d:
+ 38:86:53:ee:97:9f:a9:b2:63:94:17:8d:0f:dc:66:
+ 2a:7c:52:51:75:cb:99:8e:e8:3d:5c:bf:9e:3b:28:
+ 8d:83:02:0f:a9:9f:72:e2:2c:2b:b3:dc:66:97:00:
+ 40:d0:a4:54:8e:9b:5d:7b:45:36:26:d6:72:43:eb:
+ cf:c0:ea:0d:dc:ce:12:e6:7d:38:9f:05:27:a8:97:
+ 3e:e9:51:c6:6c:05:28:c1:02:0f:e9:18:6d:ec:bd:
+ 9c:06:d4:a7:49:f4:54:05:6b:6c:30:f1:eb:03:d5:
+ ea:3d:6a:76:c2:cb:1a:28:49:4d:7f:64:e0:fa:2b:
+ da:73:83:81:ff:91:03:bd:94:bb:e4:b8:8e:9c:32:
+ 63:cd:9f:bb:68:81:b1:84:5b:af:36:bf:77:ee:1d:
+ 7f:f7:49:9b:52:ec:d2:77:5a:7d:91:9d:4d:c2:39:
+ 2d:e4:ba:82:f8:6f:f2:4e:1e:0f:4e:e6:3f:59:a5:
+ 23:dc:3d:87:a8:28:58:28:d1:f1:1b:36:db:4f:c4:
+ ff:e1:8c:5b:72:8c:c7:26:03:27:a3:39:0a:01:aa:
+ c0:b2:31:60:83:22:a1:4f:12:09:01:11:af:34:d4:
+ cf:d7:ae:62:d3:05:07:b4:31:75:e0:0d:6d:57:4f:
+ 69:87:f9:57:a9:ba:15:f6:c8:52:6d:a1:cb:9c:1f:
+ e5:fc:78:a8:35:9a:9f:41:14:ce:a5:b4:ce:94:08:
+ 1c:09:ad:56:e5:da:b6:49:9a:4a:ea:63:18:53:9c:
+ 2c:2e:c3
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ 37:5D:A6:9A:74:32:C2:C2:F9:C7:A6:15:10:59:B8:E4:FD:E5:B8:6D
+ Signature Algorithm: sha256WithRSAEncryption
+ Signature Value:
+ af:a7:cf:de:ff:e0:bd:42:8d:4d:e5:22:96:df:68:ea:7d:4d:
+ 2a:7d:d0:ad:3d:16:5c:43:e7:7d:c0:86:e8:7a:35:63:f1:cc:
+ 81:c8:c6:0b:e8:2e:52:35:a4:a6:49:90:63:51:ac:34:ac:05:
+ 3b:57:00:e9:d3:62:d3:d9:29:d5:54:be:1c:10:91:9c:b2:6d:
+ fe:59:fd:79:f7:ea:56:d0:9e:68:54:42:8f:26:52:e2:4c:df:
+ 2f:97:a6:2f:d2:07:98:a8:f3:60:5d:4b:9a:58:57:88:ef:82:
+ e5:fa:af:6c:81:4b:92:8f:40:9a:93:46:59:cb:5f:78:16:b1:
+ 67:3e:42:0b:df:28:d9:b0:ad:98:20:be:43:7c:d1:5e:1a:09:
+ 17:24:8d:7b:5d:95:e9:ab:c1:60:ab:5b:18:64:80:fb:ad:e0:
+ 06:7d:1d:ca:59:b8:f3:78:29:67:c6:56:1d:af:b6:b5:74:2a:
+ 76:a1:3f:fb:75:30:9f:94:5e:3b:a5:60:f3:cb:5c:0c:e2:0e:
+ c9:60:f8:c9:1f:16:8a:26:dd:e7:27:7f:eb:25:a6:8a:bd:b8:
+ 2d:36:10:9a:b1:58:4d:9a:68:4f:60:54:e5:f6:46:13:8e:88:
+ ac:bc:21:42:12:ad:c6:4a:89:7d:9b:c1:d8:2d:e9:96:03:f4:
+ a2:74:0c:bc:00:1d:bf:d6:37:25:67:b4:72:8b:af:85:bd:ea:
+ 2a:03:8f:cc:fb:3c:44:24:82:e2:01:a5:0b:59:b6:34:8d:32:
+ 0b:12:0d:eb:27:c2:fd:41:d7:40:3c:72:46:29:c0:8c:ea:ba:
+ 0f:f1:06:93:2e:f7:9c:a8:f4:60:3e:a3:f1:38:5e:8e:13:c1:
+ b3:3a:97:87:3f:92:ca:78:a9:1c:af:d0:b0:1b:26:1e:be:70:
+ ec:7a:f5:33:98:ea:5c:ff:2b:0b:04:4e:43:dd:63:7e:0e:a7:
+ 4e:78:03:95:3e:d4:2d:30:95:11:10:28:2e:bf:a0:02:3e:ff:
+ 5e:59:d3:05:0e:95:5f:53:45:ef:6b:87:d5:48:cd:16:a6:96:
+ 83:e1:df:b3:06:f3:c1:14:db:a7:ec:1c:8b:5d:90:90:0d:72:
+ 51:e7:61:f9:14:ca:af:83:8f:bf:af:b1:0a:59:5d:dc:5c:d7:
+ e4:96:ad:5b:60:1d:da:ae:97:b2:39:d9:06:f5:76:00:13:f8:
+ 68:4c:21:b0:35:c4:dc:55:b2:c9:c1:41:5a:1c:89:c0:8c:6f:
+ 74:a0:6b:33:4d:b5:01:28:fd:ad:ad:89:17:3b:a6:9a:84:bc:
+ eb:8c:ea:c4:71:24:a8:ba:29:f9:08:b2:27:56:35:32:5f:ea:
+ 39:fb:31:9a:d5:19:cc:f0
+SHA1 Fingerprint=6D:0A:5F:F7:B4:23:06:B4:85:B3:B7:97:64:FC:AC:75:F5:33:F2:93
diff --git a/apex/ca-certificates/files/98aaf404.0 b/apex/ca-certificates/files/98aaf404.0
new file mode 100644
index 0000000..29a96cb
--- /dev/null
+++ b/apex/ca-certificates/files/98aaf404.0
@@ -0,0 +1,125 @@
+-----BEGIN CERTIFICATE-----
+MIIFpTCCA42gAwIBAgIUZPYOZXdhaqs7tOqFhLuxibhxkw8wDQYJKoZIhvcNAQEM
+BQAwWjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dp
+ZXMsIEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHMzAe
+Fw0yMTA1MjAwMjEwMTlaFw00NjA1MTkwMjEwMTlaMFoxCzAJBgNVBAYTAkNOMSUw
+IwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDDBtU
+cnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzMwggIiMA0GCSqGSIb3DQEBAQUAA4IC
+DwAwggIKAoICAQDAMYJhkuSUGwoqZdC+BqmHO1ES6nBBruL7dOoKjbmzTNyPtxNS
+T1QY4SxzlZHFZjtqz6xjbYdT8PfxObegQ2OwxANdV6nnRM7EoYNl9lA+sX4WuDqK
+AtCWHwDNBSHvBm3dIZwZQ0WhxeiAysKtQGIXBsaqvPPW5vxQfmZCHzyLpnl5hkA1
+nyDvP+uLRx+PjsXUjrYsyUQE49RDdT/VP68czH5GX6zfZBCK70bwkPAPLfSIC7Ep
+qq+FqklYqL9joDiR5rPmd2jE+SoZhLsO4fWvieylL1AgdB4SQXMeJNnKziyhWTXA
+yB1GJ2Faj/lN03J5Zh6fFZAhLf3ti1ZwA0pJPn9pMRJpxx5cynoTi+jm9WAPzJMs
+hH/x/Gr8m0ed262IPfN2dTPXS6TIi/n1Q1hPy8gDVI+lhXgEGvNz8teHHUGf59gX
+zhqcD0r83ERoVGjiQTz+LISGNzzNPy+i2+f3VANfWdP3kXjHi3dqFuVJhZBFcnAv
+kV34PmVACxmZySYgWmjBNb9Pp1Hx2BErW+Canig7CjoKH8GB5S7wprlppYiU5msT
+f9FkPz2ccEblooV7WIQn3MSAPmeamseaMQ4w7OYXQJXZRe0Blqq/DPNL0WP3E1jA
+uPP6Z92bfW1K/zJMtSU7/xxnD4UiWQWRkUF3gdCFTIcQcf+eQxuulXUtgQIDAQAB
+o2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEDk5PIj7zjKsK5Xf/Ih
+MBY027ySMB0GA1UdDgQWBBRA5OTyI+84yrCuV3/yITAWNNu8kjAOBgNVHQ8BAf8E
+BAMCAQYwDQYJKoZIhvcNAQEMBQADggIBACY7UeFNOPMyGLS0XuFlXsSUT9SnYaP4
+wM8zAQLpw6o1D/GUE3d3NZ4tVlFEbuHGLige/9rsR82XRBf34EzC4Xx8MnpmyFq2
+XFNFV1pF1AWZLy4jVe5jaN/TG3inEpQGAHUNcoTpLrxaatXeL1nHo+zSh2bbt1S1
+JKv0Q3jbSwTEb93mPmY+KfJLaHEih6D4sTNjduMNhXJEIlU/HHzp/LgV6FL6qj6j
+ITk1dImmasI5+njPtqzn59ZW/yOSLlALqbUHM/Q4X6RJpstlcHboCoWASzY9M/eV
+VHUl2qzEc4Jl6VL1XP04lQJqaTDFHApXB64ipCz5xUG3uOyfT0gA+QEEVcys+TIx
+xHWVBqB/0Y0n3bOppHKH/lmLmnp0Ft0WpWIp6zqW3IunaFnT63eROfjXy9mPX1on
+AX1daBli2MjN9LdyR75bl87yraKZk62Uy5P2EgmVtqvXO9A/EcswFi55gORngS1d
+7XB4tmBZrOFdRWOPyN9yaFvqHbgB8X7754qz41SgOAngPN5C8sLtLpvzHzW2Ntjj
+gKGLzZlkD8Kqq7HK9W+eQ42EVJmzbsASZthwEPEGNTNDqJwuuhQxzhB/HIbjj9LV
++Hfsm6vxL2PZQl/gZ4FkkfGXL/xuJvYz+NO1+MRiqzFRJQJ6+N1rZdVtTTDIZbpo
+FGWsJwt0ivKH
+-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 64:f6:0e:65:77:61:6a:ab:3b:b4:ea:85:84:bb:b1:89:b8:71:93:0f
+ Signature Algorithm: sha384WithRSAEncryption
+ Issuer: C=CN, O=TrustAsia Technologies, Inc., CN=TrustAsia Global Root CA G3
+ Validity
+ Not Before: May 20 02:10:19 2021 GMT
+ Not After : May 19 02:10:19 2046 GMT
+ Subject: C=CN, O=TrustAsia Technologies, Inc., CN=TrustAsia Global Root CA G3
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (4096 bit)
+ Modulus:
+ 00:c0:31:82:61:92:e4:94:1b:0a:2a:65:d0:be:06:
+ a9:87:3b:51:12:ea:70:41:ae:e2:fb:74:ea:0a:8d:
+ b9:b3:4c:dc:8f:b7:13:52:4f:54:18:e1:2c:73:95:
+ 91:c5:66:3b:6a:cf:ac:63:6d:87:53:f0:f7:f1:39:
+ b7:a0:43:63:b0:c4:03:5d:57:a9:e7:44:ce:c4:a1:
+ 83:65:f6:50:3e:b1:7e:16:b8:3a:8a:02:d0:96:1f:
+ 00:cd:05:21:ef:06:6d:dd:21:9c:19:43:45:a1:c5:
+ e8:80:ca:c2:ad:40:62:17:06:c6:aa:bc:f3:d6:e6:
+ fc:50:7e:66:42:1f:3c:8b:a6:79:79:86:40:35:9f:
+ 20:ef:3f:eb:8b:47:1f:8f:8e:c5:d4:8e:b6:2c:c9:
+ 44:04:e3:d4:43:75:3f:d5:3f:af:1c:cc:7e:46:5f:
+ ac:df:64:10:8a:ef:46:f0:90:f0:0f:2d:f4:88:0b:
+ b1:29:aa:af:85:aa:49:58:a8:bf:63:a0:38:91:e6:
+ b3:e6:77:68:c4:f9:2a:19:84:bb:0e:e1:f5:af:89:
+ ec:a5:2f:50:20:74:1e:12:41:73:1e:24:d9:ca:ce:
+ 2c:a1:59:35:c0:c8:1d:46:27:61:5a:8f:f9:4d:d3:
+ 72:79:66:1e:9f:15:90:21:2d:fd:ed:8b:56:70:03:
+ 4a:49:3e:7f:69:31:12:69:c7:1e:5c:ca:7a:13:8b:
+ e8:e6:f5:60:0f:cc:93:2c:84:7f:f1:fc:6a:fc:9b:
+ 47:9d:db:ad:88:3d:f3:76:75:33:d7:4b:a4:c8:8b:
+ f9:f5:43:58:4f:cb:c8:03:54:8f:a5:85:78:04:1a:
+ f3:73:f2:d7:87:1d:41:9f:e7:d8:17:ce:1a:9c:0f:
+ 4a:fc:dc:44:68:54:68:e2:41:3c:fe:2c:84:86:37:
+ 3c:cd:3f:2f:a2:db:e7:f7:54:03:5f:59:d3:f7:91:
+ 78:c7:8b:77:6a:16:e5:49:85:90:45:72:70:2f:91:
+ 5d:f8:3e:65:40:0b:19:99:c9:26:20:5a:68:c1:35:
+ bf:4f:a7:51:f1:d8:11:2b:5b:e0:9a:9e:28:3b:0a:
+ 3a:0a:1f:c1:81:e5:2e:f0:a6:b9:69:a5:88:94:e6:
+ 6b:13:7f:d1:64:3f:3d:9c:70:46:e5:a2:85:7b:58:
+ 84:27:dc:c4:80:3e:67:9a:9a:c7:9a:31:0e:30:ec:
+ e6:17:40:95:d9:45:ed:01:96:aa:bf:0c:f3:4b:d1:
+ 63:f7:13:58:c0:b8:f3:fa:67:dd:9b:7d:6d:4a:ff:
+ 32:4c:b5:25:3b:ff:1c:67:0f:85:22:59:05:91:91:
+ 41:77:81:d0:85:4c:87:10:71:ff:9e:43:1b:ae:95:
+ 75:2d:81
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Authority Key Identifier:
+ 40:E4:E4:F2:23:EF:38:CA:B0:AE:57:7F:F2:21:30:16:34:DB:BC:92
+ X509v3 Subject Key Identifier:
+ 40:E4:E4:F2:23:EF:38:CA:B0:AE:57:7F:F2:21:30:16:34:DB:BC:92
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ Signature Algorithm: sha384WithRSAEncryption
+ Signature Value:
+ 26:3b:51:e1:4d:38:f3:32:18:b4:b4:5e:e1:65:5e:c4:94:4f:
+ d4:a7:61:a3:f8:c0:cf:33:01:02:e9:c3:aa:35:0f:f1:94:13:
+ 77:77:35:9e:2d:56:51:44:6e:e1:c6:2e:28:1e:ff:da:ec:47:
+ cd:97:44:17:f7:e0:4c:c2:e1:7c:7c:32:7a:66:c8:5a:b6:5c:
+ 53:45:57:5a:45:d4:05:99:2f:2e:23:55:ee:63:68:df:d3:1b:
+ 78:a7:12:94:06:00:75:0d:72:84:e9:2e:bc:5a:6a:d5:de:2f:
+ 59:c7:a3:ec:d2:87:66:db:b7:54:b5:24:ab:f4:43:78:db:4b:
+ 04:c4:6f:dd:e6:3e:66:3e:29:f2:4b:68:71:22:87:a0:f8:b1:
+ 33:63:76:e3:0d:85:72:44:22:55:3f:1c:7c:e9:fc:b8:15:e8:
+ 52:fa:aa:3e:a3:21:39:35:74:89:a6:6a:c2:39:fa:78:cf:b6:
+ ac:e7:e7:d6:56:ff:23:92:2e:50:0b:a9:b5:07:33:f4:38:5f:
+ a4:49:a6:cb:65:70:76:e8:0a:85:80:4b:36:3d:33:f7:95:54:
+ 75:25:da:ac:c4:73:82:65:e9:52:f5:5c:fd:38:95:02:6a:69:
+ 30:c5:1c:0a:57:07:ae:22:a4:2c:f9:c5:41:b7:b8:ec:9f:4f:
+ 48:00:f9:01:04:55:cc:ac:f9:32:31:c4:75:95:06:a0:7f:d1:
+ 8d:27:dd:b3:a9:a4:72:87:fe:59:8b:9a:7a:74:16:dd:16:a5:
+ 62:29:eb:3a:96:dc:8b:a7:68:59:d3:eb:77:91:39:f8:d7:cb:
+ d9:8f:5f:5a:27:01:7d:5d:68:19:62:d8:c8:cd:f4:b7:72:47:
+ be:5b:97:ce:f2:ad:a2:99:93:ad:94:cb:93:f6:12:09:95:b6:
+ ab:d7:3b:d0:3f:11:cb:30:16:2e:79:80:e4:67:81:2d:5d:ed:
+ 70:78:b6:60:59:ac:e1:5d:45:63:8f:c8:df:72:68:5b:ea:1d:
+ b8:01:f1:7e:fb:e7:8a:b3:e3:54:a0:38:09:e0:3c:de:42:f2:
+ c2:ed:2e:9b:f3:1f:35:b6:36:d8:e3:80:a1:8b:cd:99:64:0f:
+ c2:aa:ab:b1:ca:f5:6f:9e:43:8d:84:54:99:b3:6e:c0:12:66:
+ d8:70:10:f1:06:35:33:43:a8:9c:2e:ba:14:31:ce:10:7f:1c:
+ 86:e3:8f:d2:d5:f8:77:ec:9b:ab:f1:2f:63:d9:42:5f:e0:67:
+ 81:64:91:f1:97:2f:fc:6e:26:f6:33:f8:d3:b5:f8:c4:62:ab:
+ 31:51:25:02:7a:f8:dd:6b:65:d5:6d:4d:30:c8:65:ba:68:14:
+ 65:ac:27:0b:74:8a:f2:87
+SHA1 Fingerprint=63:CF:B6:C1:27:2B:56:E4:88:8E:1C:23:9A:B6:2E:81:47:24:C3:C7
diff --git a/apex/ca-certificates/files/a3896b44.0 b/apex/ca-certificates/files/a3896b44.0
deleted file mode 100644
index 91c59d0..0000000
--- a/apex/ca-certificates/files/a3896b44.0
+++ /dev/null
@@ -1,78 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY
-MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t
-dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5
-WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD
-VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3
-DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8
-9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ
-DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9
-Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N
-QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ
-xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G
-A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T
-AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG
-kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr
-Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5
-Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU
-JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot
-RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw==
------END CERTIFICATE-----
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 0 (0x0)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=JP, O=SECOM Trust.net, OU=Security Communication RootCA1
- Validity
- Not Before: Sep 30 04:20:49 2003 GMT
- Not After : Sep 30 04:20:49 2023 GMT
- Subject: C=JP, O=SECOM Trust.net, OU=Security Communication RootCA1
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:b3:b3:fe:7f:d3:6d:b1:ef:16:7c:57:a5:0c:6d:
- 76:8a:2f:4b:bf:64:fb:4c:ee:8a:f0:f3:29:7c:f5:
- ff:ee:2a:e0:e9:e9:ba:5b:64:22:9a:9a:6f:2c:3a:
- 26:69:51:05:99:26:dc:d5:1c:6a:71:c6:9a:7d:1e:
- 9d:dd:7c:6c:c6:8c:67:67:4a:3e:f8:71:b0:19:27:
- a9:09:0c:a6:95:bf:4b:8c:0c:fa:55:98:3b:d8:e8:
- 22:a1:4b:71:38:79:ac:97:92:69:b3:89:7e:ea:21:
- 68:06:98:14:96:87:d2:61:36:bc:6d:27:56:9e:57:
- ee:c0:c0:56:fd:32:cf:a4:d9:8e:c2:23:d7:8d:a8:
- f3:d8:25:ac:97:e4:70:38:f4:b6:3a:b4:9d:3b:97:
- 26:43:a3:a1:bc:49:59:72:4c:23:30:87:01:58:f6:
- 4e:be:1c:68:56:66:af:cd:41:5d:c8:b3:4d:2a:55:
- 46:ab:1f:da:1e:e2:40:3d:db:cd:7d:b9:92:80:9c:
- 37:dd:0c:96:64:9d:dc:22:f7:64:8b:df:61:de:15:
- 94:52:15:a0:7d:52:c9:4b:a8:21:c9:c6:b1:ed:cb:
- c3:95:60:d1:0f:f0:ab:70:f8:df:cb:4d:7e:ec:d6:
- fa:ab:d9:bd:7f:54:f2:a5:e9:79:fa:d9:d6:76:24:
- 28:73
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Subject Key Identifier:
- A0:73:49:99:68:DC:85:5B:65:E3:9B:28:2F:57:9F:BD:33:BC:07:48
- X509v3 Key Usage:
- Certificate Sign, CRL Sign
- X509v3 Basic Constraints: critical
- CA:TRUE
- Signature Algorithm: sha1WithRSAEncryption
- Signature Value:
- 68:40:a9:a8:bb:e4:4f:5d:79:b3:05:b5:17:b3:60:13:eb:c6:
- 92:5d:e0:d1:d3:6a:fe:fb:be:9b:6d:bf:c7:05:6d:59:20:c4:
- 1c:f0:b7:da:84:58:02:63:fa:48:16:ef:4f:a5:0b:f7:4a:98:
- f2:3f:9e:1b:ad:47:6b:63:ce:08:47:eb:52:3f:78:9c:af:4d:
- ae:f8:d5:4f:cf:9a:98:2a:10:41:39:52:c4:dd:d9:9b:0e:ef:
- 93:01:ae:b2:2e:ca:68:42:24:42:6c:b0:b3:3a:3e:cd:e9:da:
- 48:c4:15:cb:e9:f9:07:0f:92:50:49:8a:dd:31:97:5f:c9:e9:
- 37:aa:3b:59:65:97:94:32:c9:b3:9f:3e:3a:62:58:c5:49:ad:
- 62:0e:71:a5:32:aa:2f:c6:89:76:43:40:13:13:67:3d:a2:54:
- 25:10:cb:f1:3a:f2:d9:fa:db:49:56:bb:a6:fe:a7:41:35:c3:
- e0:88:61:c9:88:c7:df:36:10:22:98:59:ea:b0:4a:fb:56:16:
- 73:6e:ac:4d:f7:22:a1:4f:ad:1d:7a:2d:45:27:e5:30:c1:5e:
- f2:da:13:cb:25:42:51:95:47:03:8c:6c:21:cc:74:42:ed:53:
- ff:33:8b:8f:0f:57:01:16:2f:cf:a6:ee:c9:70:22:14:bd:fd:
- be:6c:0b:03
-SHA1 Fingerprint=36:B1:2B:49:F9:81:9E:D7:4C:9E:BC:38:0F:C6:56:8F:5D:AC:B2:F7
diff --git a/apex/ca-certificates/files/cbb3f32b.0 b/apex/ca-certificates/files/cbb3f32b.0
new file mode 100644
index 0000000..73c7e7e
--- /dev/null
+++ b/apex/ca-certificates/files/cbb3f32b.0
@@ -0,0 +1,56 @@
+-----BEGIN CERTIFICATE-----
+MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQsw
+CQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxT
+U0wuY29tIFRMUyBFQ0MgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2
+MDgxOTE2MzM0N1owTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jwb3Jh
+dGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgRUNDIFJvb3QgQ0EgMjAyMjB2MBAG
+ByqGSM49AgEGBSuBBAAiA2IABEUpNXP6wrgjzhR9qLFNoFs27iosU8NgCTWyJGYm
+acCzldZdkkAZDsalE3D07xJRKF3nzL35PIXBz5SQySvOkkJYWWf9lCcQZIxPBLFN
+SeR7T5v15wj4A4j3p8OSSxlUgaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSME
+GDAWgBSJjy+j6CugFFR781a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NW
+uCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp
+15IkWE8elDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w7deedWo1dlJF4AIxAMeN
+b0Igj762TVntd00pxCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5Zn6g6g==
+-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 14:03:f5:ab:fb:37:8b:17:40:5b:e2:43:b2:a5:d1:c4
+ Signature Algorithm: ecdsa-with-SHA384
+ Issuer: C=US, O=SSL Corporation, CN=SSL.com TLS ECC Root CA 2022
+ Validity
+ Not Before: Aug 25 16:33:48 2022 GMT
+ Not After : Aug 19 16:33:47 2046 GMT
+ Subject: C=US, O=SSL Corporation, CN=SSL.com TLS ECC Root CA 2022
+ Subject Public Key Info:
+ Public Key Algorithm: id-ecPublicKey
+ Public-Key: (384 bit)
+ pub:
+ 04:45:29:35:73:fa:c2:b8:23:ce:14:7d:a8:b1:4d:
+ a0:5b:36:ee:2a:2c:53:c3:60:09:35:b2:24:66:26:
+ 69:c0:b3:95:d6:5d:92:40:19:0e:c6:a5:13:70:f4:
+ ef:12:51:28:5d:e7:cc:bd:f9:3c:85:c1:cf:94:90:
+ c9:2b:ce:92:42:58:59:67:fd:94:27:10:64:8c:4f:
+ 04:b1:4d:49:e4:7b:4f:9b:f5:e7:08:f8:03:88:f7:
+ a7:c3:92:4b:19:54:81
+ ASN1 OID: secp384r1
+ NIST CURVE: P-384
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Authority Key Identifier:
+ 89:8F:2F:A3:E8:2B:A0:14:54:7B:F3:56:B8:26:5F:67:38:0B:9C:D0
+ X509v3 Subject Key Identifier:
+ 89:8F:2F:A3:E8:2B:A0:14:54:7B:F3:56:B8:26:5F:67:38:0B:9C:D0
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ Signature Algorithm: ecdsa-with-SHA384
+ Signature Value:
+ 30:65:02:30:55:e3:22:56:e9:d7:92:24:58:4f:1e:94:32:0f:
+ 0c:02:36:c2:fd:ac:74:32:4e:e1:fb:1c:80:88:a3:cc:fb:d7:
+ eb:2b:ff:37:7d:f0:ed:d7:9e:75:6a:35:76:52:45:e0:02:31:
+ 00:c7:8d:6f:42:20:8f:be:b6:4d:59:ed:77:4d:29:c4:20:20:
+ 45:64:86:3a:50:c6:c4:ad:2d:93:f5:18:7d:72:ed:a9:cf:c4:
+ ac:57:36:28:08:65:df:3c:79:66:7e:a0:ea
+SHA1 Fingerprint=9F:5F:D9:1A:54:6D:F5:0C:71:F0:EE:7A:BD:17:49:98:84:73:E2:39
diff --git a/apex/ca-certificates/files/d16a5865.0 b/apex/ca-certificates/files/d16a5865.0
index be02f3d..a81824c 100644
--- a/apex/ca-certificates/files/d16a5865.0
+++ b/apex/ca-certificates/files/d16a5865.0
@@ -1,8 +1,8 @@
-----BEGIN CERTIFICATE-----
-MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE
+MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UE
BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h
-cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy
-MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg
+cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1
+MDUxNTIyMDdaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg
Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi
MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9
thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM
@@ -15,33 +15,33 @@
EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T
KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF
6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh
-OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD
-VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD
-VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp
-cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv
-ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl
-AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF
-661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9
-am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1
-ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481
-PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS
-3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k
-SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF
-3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM
-ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g
-StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz
-Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB
-jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V
+OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMB0GA1UdDgQWBBRlzeurNR4APn7VdMAc
+tHNHDhpkLzASBgNVHRMBAf8ECDAGAQH/AgEBMIGmBgNVHSAEgZ4wgZswgZgGBFUd
+IAAwgY8wLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuZmlybWFwcm9mZXNpb25hbC5j
+b20vY3BzMFwGCCsGAQUFBwICMFAeTgBQAGEAcwBlAG8AIABkAGUAIABsAGEAIABC
+AG8AbgBhAG4AbwB2AGEAIAA0ADcAIABCAGEAcgBjAGUAbABvAG4AYQAgADAAOAAw
+ADEANzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAHSHKAIrdx9m
+iWTtj3QuRhy7qPj4Cx2Dtjqn6EWKB7fgPiDL4QjbEwj4KKE1soCzC1HA01aajTNF
+Sa9J8OA9B3pFE1r/yJfY0xgsfZb43aJlQ3CTkBW6kN/oGbDbLIpgD7dvlAceHabJ
+hfa9NPhAeGIQcDq+fUs5gakQ1JZBu/hfHAsdCPKxsIl68veg4MSPi3i1O1ilI45P
+Vf42O+AMt8oqMEEgtIDNrvx2ZnOorm7hfNoD6JQg5iKj0B+QXSBTFCZX2lSX3xZE
+EAEeiGaPcjiT3SC3NL7X8e5jjkd5KAb881lFJWAiMxujX6i6KtoaPc1A6ozuBRWV
+1aUsIC+nmCjuRfzxuIgALI9C2lHVnOUTaHFFQ4ueCyE8S1wF3BqfmI7avSKecs2t
+CsvMo2ebKHTEm9caPARYpoKdrcd7b/+Alun4jWq9GJAd/0kakFI3ky88Al2CdgtR
+5xbHV/g4+afNmyJU72OwFW1TZQNKXkqgsqeOSQBZONXH9IBk9W6VULgRfhVwOEqw
+f9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpfNIbnYrX9
+ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNK
+GbqEZycPvEJdvSRUDewdcAZfpLz6IHxV
-----END CERTIFICATE-----
Certificate:
Data:
Version: 3 (0x2)
- Serial Number: 6047274297262753887 (0x53ec3beefbb2485f)
- Signature Algorithm: sha1WithRSAEncryption
+ Serial Number: 1977337328857672817 (0x1b70e9d2ffae6c71)
+ Signature Algorithm: sha256WithRSAEncryption
Issuer: C=ES, CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
Validity
- Not Before: May 20 08:38:15 2009 GMT
- Not After : Dec 31 08:38:15 2030 GMT
+ Not Before: Sep 23 15:22:07 2014 GMT
+ Not After : May 5 15:22:07 2036 GMT
Subject: C=ES, CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
@@ -84,46 +84,46 @@
92:30:bb
Exponent: 65537 (0x10001)
X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:1
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
X509v3 Subject Key Identifier:
65:CD:EB:AB:35:1E:00:3E:7E:D5:74:C0:1C:B4:73:47:0E:1A:64:2F
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:1
X509v3 Certificate Policies:
Policy: X509v3 Any Policy
CPS: http://www.firmaprofesional.com/cps
User Notice:
Explicit Text:
- Signature Algorithm: sha1WithRSAEncryption
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ Signature Algorithm: sha256WithRSAEncryption
Signature Value:
- 17:7d:a0:f9:b4:dd:c5:c5:eb:ad:4b:24:b5:a1:02:ab:dd:a5:
- 88:4a:b2:0f:55:4b:2b:57:8c:3b:e5:31:dd:fe:c4:32:f1:e7:
- 5b:64:96:36:32:18:ec:a5:32:77:d7:e3:44:b6:c0:11:2a:80:
- b9:3d:6a:6e:7c:9b:d3:ad:fc:c3:d6:a3:e6:64:29:7c:d1:e1:
- 38:1e:82:2b:ff:27:65:af:fb:16:15:c4:2e:71:84:e5:b5:ff:
- fa:a4:47:bd:64:32:bb:f6:25:84:a2:27:42:f5:20:b0:c2:13:
- 10:11:cd:10:15:ba:42:90:2a:d2:44:e1:96:26:eb:31:48:12:
- fd:2a:da:c9:06:cf:74:1e:a9:4b:d5:87:28:f9:79:34:92:3e:
- 2e:44:e8:f6:8f:4f:8f:35:3f:25:b3:39:dc:63:2a:90:6b:20:
- 5f:c4:52:12:4e:97:2c:2a:ac:9d:97:de:48:f2:a3:66:db:c2:
- d2:83:95:a6:66:a7:9e:25:0f:e9:0b:33:91:65:0a:5a:c3:d9:
- 54:12:dd:af:c3:4e:0e:1f:26:5e:0d:dc:b3:8d:ec:d5:81:70:
- de:d2:4f:24:05:f3:6c:4e:f5:4c:49:66:8d:d1:ff:d2:0b:25:
- 41:48:fe:51:84:c6:42:af:80:04:cf:d0:7e:64:49:e4:f2:df:
- a2:ec:b1:4c:c0:2a:1d:e7:b4:b1:65:a2:c4:bc:f1:98:f4:aa:
- 70:07:63:b4:b8:da:3b:4c:fa:40:22:30:5b:11:a6:f0:05:0e:
- c6:02:03:48:ab:86:9b:85:dd:db:dd:ea:a2:76:80:73:7d:f5:
- 9c:04:c4:45:8d:e7:b9:1c:8b:9e:ea:d7:75:d1:72:b1:de:75:
- 44:e7:42:7d:e2:57:6b:7d:dc:99:bc:3d:83:28:ea:80:93:8d:
- c5:4c:65:c1:70:81:b8:38:fc:43:31:b2:f6:03:34:47:b2:ac:
- fb:22:06:cb:1e:dd:17:47:1c:5f:66:b9:d3:1a:a2:da:11:b1:
- a4:bc:23:c9:e4:be:87:ff:b9:94:b6:f8:5d:20:4a:d4:5f:e7:
- bd:68:7b:65:f2:15:1e:d2:3a:a9:2d:e9:d8:6b:24:ac:97:58:
- 44:47:ad:59:18:f1:21:65:70:de:ce:34:60:a8:40:f1:f3:3c:
- a4:c3:28:23:8c:fe:27:33:43:40:a0:17:3c:eb:ea:3b:b0:72:
- a6:a3:b9:4a:4b:5e:16:48:f4:b2:bc:c8:8c:92:c5:9d:9f:ac:
- 72:36:bc:34:80:34:6b:a9:8b:92:c0:b8:17:ed:ec:76:53:f5:
- 24:01:8c:b3:22:e8:4b:7c:55:c6:9d:fa:a3:14:bb:65:85:6e:
- 6e:4f:12:7e:0a:3c:9d:95
-SHA1 Fingerprint=AE:C5:FB:3F:C8:E1:BF:C4:E5:4F:03:07:5A:9A:E8:00:B7:F7:B6:FA
+ 74:87:28:02:2b:77:1f:66:89:64:ed:8f:74:2e:46:1c:bb:a8:
+ f8:f8:0b:1d:83:b6:3a:a7:e8:45:8a:07:b7:e0:3e:20:cb:e1:
+ 08:db:13:08:f8:28:a1:35:b2:80:b3:0b:51:c0:d3:56:9a:8d:
+ 33:45:49:af:49:f0:e0:3d:07:7a:45:13:5a:ff:c8:97:d8:d3:
+ 18:2c:7d:96:f8:dd:a2:65:43:70:93:90:15:ba:90:df:e8:19:
+ b0:db:2c:8a:60:0f:b7:6f:94:07:1e:1d:a6:c9:85:f6:bd:34:
+ f8:40:78:62:10:70:3a:be:7d:4b:39:81:a9:10:d4:96:41:bb:
+ f8:5f:1c:0b:1d:08:f2:b1:b0:89:7a:f2:f7:a0:e0:c4:8f:8b:
+ 78:b5:3b:58:a5:23:8e:4f:55:fe:36:3b:e0:0c:b7:ca:2a:30:
+ 41:20:b4:80:cd:ae:fc:76:66:73:a8:ae:6e:e1:7c:da:03:e8:
+ 94:20:e6:22:a3:d0:1f:90:5d:20:53:14:26:57:da:54:97:df:
+ 16:44:10:01:1e:88:66:8f:72:38:93:dd:20:b7:34:be:d7:f1:
+ ee:63:8e:47:79:28:06:fc:f3:59:45:25:60:22:33:1b:a3:5f:
+ a8:ba:2a:da:1a:3d:cd:40:ea:8c:ee:05:15:95:d5:a5:2c:20:
+ 2f:a7:98:28:ee:45:fc:f1:b8:88:00:2c:8f:42:da:51:d5:9c:
+ e5:13:68:71:45:43:8b:9e:0b:21:3c:4b:5c:05:dc:1a:9f:98:
+ 8e:da:bd:22:9e:72:cd:ad:0a:cb:cc:a3:67:9b:28:74:c4:9b:
+ d7:1a:3c:04:58:a6:82:9d:ad:c7:7b:6f:ff:80:96:e9:f8:8d:
+ 6a:bd:18:90:1d:ff:49:1a:90:52:37:93:2f:3c:02:5d:82:76:
+ 0b:51:e7:16:c7:57:f8:38:f9:a7:cd:9b:22:54:ef:63:b0:15:
+ 6d:53:65:03:4a:5e:4a:a0:b2:a7:8e:49:00:59:38:d5:c7:f4:
+ 80:64:f5:6e:95:50:b8:11:7e:15:70:38:4a:b0:7f:d0:c4:32:
+ 70:c0:19:ff:c9:38:2d:14:2c:66:f4:42:44:e6:55:76:1b:80:
+ 15:57:ff:c0:a7:a7:aa:39:aa:d8:d3:70:d0:2e:ba:eb:94:6a:
+ fa:5f:34:86:e7:62:b5:fd:8a:f0:30:85:94:c9:af:24:02:2f:
+ 6f:d6:dd:67:fe:e3:b0:55:4f:04:98:4f:a4:41:56:e2:93:d0:
+ 6a:e8:d6:f3:fb:65:e0:ce:75:c4:31:59:0c:ee:82:c8:0c:60:
+ 33:4a:19:ba:84:67:27:0f:bc:42:5d:bd:24:54:0d:ec:1d:70:
+ 06:5f:a4:bc:fa:20:7c:55
+SHA1 Fingerprint=0B:BE:C2:27:22:49:CB:39:AA:DB:35:5C:53:E3:8C:AE:78:FF:B6:FE
diff --git a/apex/ca-certificates/files/d16a5865.1 b/apex/ca-certificates/files/d16a5865.1
deleted file mode 100644
index a81824c..0000000
--- a/apex/ca-certificates/files/d16a5865.1
+++ /dev/null
@@ -1,129 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UE
-BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h
-cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1
-MDUxNTIyMDdaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg
-Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi
-MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9
-thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM
-cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG
-L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i
-NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h
-X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b
-m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy
-Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja
-EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T
-KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF
-6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh
-OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMB0GA1UdDgQWBBRlzeurNR4APn7VdMAc
-tHNHDhpkLzASBgNVHRMBAf8ECDAGAQH/AgEBMIGmBgNVHSAEgZ4wgZswgZgGBFUd
-IAAwgY8wLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuZmlybWFwcm9mZXNpb25hbC5j
-b20vY3BzMFwGCCsGAQUFBwICMFAeTgBQAGEAcwBlAG8AIABkAGUAIABsAGEAIABC
-AG8AbgBhAG4AbwB2AGEAIAA0ADcAIABCAGEAcgBjAGUAbABvAG4AYQAgADAAOAAw
-ADEANzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAHSHKAIrdx9m
-iWTtj3QuRhy7qPj4Cx2Dtjqn6EWKB7fgPiDL4QjbEwj4KKE1soCzC1HA01aajTNF
-Sa9J8OA9B3pFE1r/yJfY0xgsfZb43aJlQ3CTkBW6kN/oGbDbLIpgD7dvlAceHabJ
-hfa9NPhAeGIQcDq+fUs5gakQ1JZBu/hfHAsdCPKxsIl68veg4MSPi3i1O1ilI45P
-Vf42O+AMt8oqMEEgtIDNrvx2ZnOorm7hfNoD6JQg5iKj0B+QXSBTFCZX2lSX3xZE
-EAEeiGaPcjiT3SC3NL7X8e5jjkd5KAb881lFJWAiMxujX6i6KtoaPc1A6ozuBRWV
-1aUsIC+nmCjuRfzxuIgALI9C2lHVnOUTaHFFQ4ueCyE8S1wF3BqfmI7avSKecs2t
-CsvMo2ebKHTEm9caPARYpoKdrcd7b/+Alun4jWq9GJAd/0kakFI3ky88Al2CdgtR
-5xbHV/g4+afNmyJU72OwFW1TZQNKXkqgsqeOSQBZONXH9IBk9W6VULgRfhVwOEqw
-f9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpfNIbnYrX9
-ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNK
-GbqEZycPvEJdvSRUDewdcAZfpLz6IHxV
------END CERTIFICATE-----
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 1977337328857672817 (0x1b70e9d2ffae6c71)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=ES, CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
- Validity
- Not Before: Sep 23 15:22:07 2014 GMT
- Not After : May 5 15:22:07 2036 GMT
- Subject: C=ES, CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (4096 bit)
- Modulus:
- 00:ca:96:6b:8e:ea:f8:fb:f1:a2:35:e0:7f:4c:da:
- e0:c3:52:d7:7d:b6:10:c8:02:5e:b3:43:2a:c4:4f:
- 6a:b2:ca:1c:5d:28:9a:78:11:1a:69:59:57:af:b5:
- 20:42:e4:8b:0f:e6:df:5b:a6:03:92:2f:f5:11:e4:
- 62:d7:32:71:38:d9:04:0c:71:ab:3d:51:7e:0f:07:
- df:63:05:5c:e9:bf:94:6f:c1:29:82:c0:b4:da:51:
- b0:c1:3c:bb:ad:37:4a:5c:ca:f1:4b:36:0e:24:ab:
- bf:c3:84:77:fd:a8:50:f4:b1:e7:c6:2f:d2:2d:59:
- 8d:7a:0a:4e:96:69:52:02:aa:36:98:ec:fc:fa:14:
- 83:0c:37:1f:c9:92:37:7f:d7:81:2d:e5:c4:b9:e0:
- 3e:34:fe:67:f4:3e:66:d1:d3:f4:40:cf:5e:62:34:
- 0f:70:06:3e:20:18:5a:ce:f7:72:1b:25:6c:93:74:
- 14:93:a3:73:b1:0e:aa:87:10:23:59:5f:20:05:19:
- 47:ed:68:8e:92:12:ca:5d:fc:d6:2b:b2:92:3c:20:
- cf:e1:5f:af:20:be:a0:76:7f:76:e5:ec:1a:86:61:
- 33:3e:e7:7b:b4:3f:a0:0f:8e:a2:b9:6a:6f:b9:87:
- 26:6f:41:6c:88:a6:50:fd:6a:63:0b:f5:93:16:1b:
- 19:8f:b2:ed:9b:9b:c9:90:f5:01:0c:df:19:3d:0f:
- 3e:38:23:c9:2f:8f:0c:d1:02:fe:1b:55:d6:4e:d0:
- 8d:3c:af:4f:a4:f3:fe:af:2a:d3:05:9d:79:08:a1:
- cb:57:31:b4:9c:c8:90:b2:67:f4:18:16:93:3a:fc:
- 47:d8:d1:78:96:31:1f:ba:2b:0c:5f:5d:99:ad:63:
- 89:5a:24:20:76:d8:df:fd:ab:4e:a6:22:aa:9d:5e:
- e6:27:8a:7d:68:29:a3:e7:8a:b8:da:11:bb:17:2d:
- 99:9d:13:24:46:f7:c5:e2:d8:9f:8e:7f:c7:8f:74:
- 6d:5a:b2:e8:72:f5:ac:ee:24:10:ad:2f:14:da:ff:
- 2d:9a:46:71:47:be:42:df:bb:01:db:f4:7f:d3:28:
- 8f:31:59:5b:d3:c9:02:a6:b4:52:ca:6e:97:fb:43:
- c5:08:26:6f:8a:f4:bb:fd:9f:28:aa:0d:d5:45:f3:
- 13:3a:1d:d8:c0:78:8f:41:67:3c:1e:94:64:ae:7b:
- 0b:c5:e8:d9:01:88:39:1a:97:86:64:41:d5:3b:87:
- 0c:6e:fa:0f:c6:bd:48:14:bf:39:4d:d4:9e:41:b6:
- 8f:96:1d:63:96:93:d9:95:06:78:31:68:9e:37:06:
- 3b:80:89:45:61:39:23:c7:1b:44:a3:15:e5:1c:f8:
- 92:30:bb
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Subject Key Identifier:
- 65:CD:EB:AB:35:1E:00:3E:7E:D5:74:C0:1C:B4:73:47:0E:1A:64:2F
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:1
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: http://www.firmaprofesional.com/cps
- User Notice:
- Explicit Text:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- Signature Algorithm: sha256WithRSAEncryption
- Signature Value:
- 74:87:28:02:2b:77:1f:66:89:64:ed:8f:74:2e:46:1c:bb:a8:
- f8:f8:0b:1d:83:b6:3a:a7:e8:45:8a:07:b7:e0:3e:20:cb:e1:
- 08:db:13:08:f8:28:a1:35:b2:80:b3:0b:51:c0:d3:56:9a:8d:
- 33:45:49:af:49:f0:e0:3d:07:7a:45:13:5a:ff:c8:97:d8:d3:
- 18:2c:7d:96:f8:dd:a2:65:43:70:93:90:15:ba:90:df:e8:19:
- b0:db:2c:8a:60:0f:b7:6f:94:07:1e:1d:a6:c9:85:f6:bd:34:
- f8:40:78:62:10:70:3a:be:7d:4b:39:81:a9:10:d4:96:41:bb:
- f8:5f:1c:0b:1d:08:f2:b1:b0:89:7a:f2:f7:a0:e0:c4:8f:8b:
- 78:b5:3b:58:a5:23:8e:4f:55:fe:36:3b:e0:0c:b7:ca:2a:30:
- 41:20:b4:80:cd:ae:fc:76:66:73:a8:ae:6e:e1:7c:da:03:e8:
- 94:20:e6:22:a3:d0:1f:90:5d:20:53:14:26:57:da:54:97:df:
- 16:44:10:01:1e:88:66:8f:72:38:93:dd:20:b7:34:be:d7:f1:
- ee:63:8e:47:79:28:06:fc:f3:59:45:25:60:22:33:1b:a3:5f:
- a8:ba:2a:da:1a:3d:cd:40:ea:8c:ee:05:15:95:d5:a5:2c:20:
- 2f:a7:98:28:ee:45:fc:f1:b8:88:00:2c:8f:42:da:51:d5:9c:
- e5:13:68:71:45:43:8b:9e:0b:21:3c:4b:5c:05:dc:1a:9f:98:
- 8e:da:bd:22:9e:72:cd:ad:0a:cb:cc:a3:67:9b:28:74:c4:9b:
- d7:1a:3c:04:58:a6:82:9d:ad:c7:7b:6f:ff:80:96:e9:f8:8d:
- 6a:bd:18:90:1d:ff:49:1a:90:52:37:93:2f:3c:02:5d:82:76:
- 0b:51:e7:16:c7:57:f8:38:f9:a7:cd:9b:22:54:ef:63:b0:15:
- 6d:53:65:03:4a:5e:4a:a0:b2:a7:8e:49:00:59:38:d5:c7:f4:
- 80:64:f5:6e:95:50:b8:11:7e:15:70:38:4a:b0:7f:d0:c4:32:
- 70:c0:19:ff:c9:38:2d:14:2c:66:f4:42:44:e6:55:76:1b:80:
- 15:57:ff:c0:a7:a7:aa:39:aa:d8:d3:70:d0:2e:ba:eb:94:6a:
- fa:5f:34:86:e7:62:b5:fd:8a:f0:30:85:94:c9:af:24:02:2f:
- 6f:d6:dd:67:fe:e3:b0:55:4f:04:98:4f:a4:41:56:e2:93:d0:
- 6a:e8:d6:f3:fb:65:e0:ce:75:c4:31:59:0c:ee:82:c8:0c:60:
- 33:4a:19:ba:84:67:27:0f:bc:42:5d:bd:24:54:0d:ec:1d:70:
- 06:5f:a4:bc:fa:20:7c:55
-SHA1 Fingerprint=0B:BE:C2:27:22:49:CB:39:AA:DB:35:5C:53:E3:8C:AE:78:FF:B6:FE
diff --git a/apex/ca-certificates/files/e071171e.0 b/apex/ca-certificates/files/e071171e.0
new file mode 100644
index 0000000..2c9146c
--- /dev/null
+++ b/apex/ca-certificates/files/e071171e.0
@@ -0,0 +1,122 @@
+-----BEGIN CERTIFICATE-----
+MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBf
+MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQD
+Ey1TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYw
+HhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEY
+MBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1Ymxp
+YyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB
+AQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDa
+ef0rty2k1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnz
+SDBh+oF8HqcIStw+KxwfGExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xf
+iOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMPFF1bFOdLvt30yNoDN9HWOaEhUTCDsG3X
+ME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vuZDCQOc2TZYEhMbUjUDM3
+IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5QazYw6A3OAS
+VYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgE
+SJ/AwSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu
++Zd4KKTIRJLpfSYFplhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt
+8uaZFURww3y8nDnAtOFr94MlI1fZEoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+L
+HaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW6aWWrL3DkJiy4Pmi1KZHQ3xt
+zwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWIIUkwDgYDVR0P
+AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c
+mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQ
+YKlJfp/imTYpE0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52
+gDY9hAaLMyZlbcp+nv4fjFg4exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZA
+Fv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M0ejf5lG5Nkc/kLnHvALcWxxPDkjB
+JYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI84HxZmduTILA7rpX
+DhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9mpFui
+TdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5
+dHn5HrwdVw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65
+LvKRRFHQV80MNNVIIb/bE/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp
+0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmmJ1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAY
+QqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL
+-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 75:8d:fd:8b:ae:7c:07:00:fa:a9:25:a7:e1:c7:ad:14
+ Signature Algorithm: sha384WithRSAEncryption
+ Issuer: C=GB, O=Sectigo Limited, CN=Sectigo Public Server Authentication Root R46
+ Validity
+ Not Before: Mar 22 00:00:00 2021 GMT
+ Not After : Mar 21 23:59:59 2046 GMT
+ Subject: C=GB, O=Sectigo Limited, CN=Sectigo Public Server Authentication Root R46
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (4096 bit)
+ Modulus:
+ 00:93:be:d5:36:52:75:d8:01:23:a0:1c:47:42:49:
+ ee:63:b6:b7:21:fd:c4:95:d5:48:2b:26:7c:14:53:
+ 10:da:79:fd:2b:b7:2d:a4:d4:2c:fa:ea:32:dd:49:
+ c2:b9:bd:0f:48:3d:7b:5a:98:54:af:9e:5d:31:74:
+ 4f:07:fc:50:21:dd:a4:cf:68:4f:1b:12:63:6d:25:
+ 99:4c:2a:99:f3:48:30:61:fa:81:7c:1e:a7:08:4a:
+ dc:3e:2b:1c:1f:18:4c:71:aa:35:8c:ad:f8:6e:e8:
+ 3b:4a:d9:e5:94:02:d6:89:84:13:aa:6d:c8:4f:33:
+ cc:50:96:37:92:33:dc:5f:88:e7:9f:54:d9:48:f0:
+ 98:43:d6:66:fd:9f:17:38:43:c5:01:51:0b:d7:e3:
+ 23:0f:14:5d:5b:14:e7:4b:be:dd:f4:c8:da:03:37:
+ d1:d6:39:a1:21:51:30:83:b0:6d:d7:30:4e:96:5b:
+ 91:f0:70:24:ab:bf:45:81:64:43:0d:bd:21:3a:2f:
+ 3c:e9:9e:0d:cb:20:b5:42:27:cc:da:6f:9b:ee:64:
+ 30:90:39:cd:93:65:81:21:31:b5:23:50:33:37:22:
+ e3:38:ed:f8:31:30:cc:45:fe:62:f9:d1:5d:32:79:
+ 42:87:df:6a:cc:56:19:40:4d:ce:aa:bb:f9:b5:76:
+ 49:94:f1:27:f8:91:a5:83:e5:06:b3:63:0e:80:dc:
+ e0:12:55:80:a6:3b:66:b4:39:87:2d:c8:f0:d0:d1:
+ 14:e9:e4:0d:4d:0e:f6:5d:57:72:c5:3b:1c:47:56:
+ 9d:e2:d5:fb:81:61:8c:cc:4d:80:90:34:5b:b7:d7:
+ 14:75:dc:d8:04:48:9f:c0:c1:28:88:b4:e9:1c:ca:
+ a7:b1:f1:56:b7:7b:49:4c:59:e5:20:15:a8:84:02:
+ 29:fa:38:94:69:9a:49:06:8f:cd:1f:79:14:17:12:
+ 0c:83:7a:de:1f:b1:97:ee:f9:97:78:28:a4:c8:44:
+ 92:e9:7d:26:05:a6:58:72:9b:79:13:d8:11:5f:ae:
+ c5:38:62:34:68:b2:86:30:8e:f8:90:61:9e:32:6c:
+ f5:07:36:cd:a2:4c:6e:ec:8a:36:ed:f2:e6:99:15:
+ 44:70:c3:7c:bc:9c:39:c0:b4:e1:6b:f7:83:25:23:
+ 57:d9:12:80:e5:49:f0:75:0f:ef:8d:eb:1c:9b:54:
+ 28:b4:21:3c:fc:7c:0a:ff:ef:7b:6b:75:ff:8b:1d:
+ a0:19:05:ab:fa:f8:2b:81:42:e8:38:ba:bb:fb:aa:
+ fd:3d:e0:f3:ca:df:4e:97:97:29:ed:f3:18:56:e9:
+ a5:96:ac:bd:c3:90:98:b2:e0:f9:a2:d4:a6:47:43:
+ 7c:6d:cf
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 56:73:58:64:95:F9:92:1A:B0:12:2A:04:62:79:A1:40:15:88:21:49
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ Signature Algorithm: sha384WithRSAEncryption
+ Signature Value:
+ 2f:5c:99:3c:fc:06:5e:8c:94:2e:70:ea:d2:32:31:8d:b4:f0:
+ 51:d5:bc:0a:f3:64:9f:07:5e:d5:c1:73:68:64:7a:a2:b9:0e:
+ e8:f9:5d:85:2d:a8:37:45:aa:28:f4:96:05:50:60:a9:49:7e:
+ 9f:e2:99:36:29:13:44:47:6a:9d:55:20:3c:d8:9b:f1:03:32:
+ ba:da:40:a1:73:ea:83:a1:b7:44:a6:0e:99:01:9b:e4:bc:7f:
+ be:13:94:7e:ca:a6:1e:76:80:36:3d:84:06:8b:33:26:65:6d:
+ ca:7e:9e:fe:1f:8c:58:38:7b:1a:83:b1:0f:bc:17:11:bb:e6:
+ 06:cc:63:fa:81:f2:81:4c:da:0b:10:6b:a1:fa:d5:28:a5:cf:
+ 06:40:16:ff:7b:7d:18:5e:39:12:a4:53:9e:7e:32:42:10:a6:
+ 21:91:a9:1c:4e:17:7c:84:bc:9f:8c:d1:e8:df:e6:51:b9:36:
+ 47:3f:90:b9:c7:bc:02:dc:5b:1c:4f:0e:48:c1:25:83:9c:0a:
+ 3f:9e:b1:03:33:12:1a:27:ac:f7:22:6c:24:d1:01:41:f8:58:
+ 03:fe:25:68:22:1f:9a:5a:3c:7c:6c:9e:75:48:f3:81:f1:66:
+ 67:6e:4c:82:c0:ee:ba:57:0e:18:ef:2e:9a:f7:12:d8:a0:6b:
+ e9:05:a5:a1:e9:68:f8:bc:4c:3f:12:1e:45:e8:52:c0:a3:bf:
+ 12:27:79:b9:cc:31:3c:c3:f6:3a:22:16:03:a0:c9:8f:66:a4:
+ 5b:a2:4d:d6:81:25:06:e9:76:a4:00:0a:3e:cb:cd:35:9b:e0:
+ e1:38:cb:60:53:86:28:42:41:1c:44:57:e8:a8:ad:ab:45:e3:
+ 25:10:bc:db:3e:65:41:fb:1b:a6:97:0f:eb:b9:74:79:f9:1e:
+ bc:1d:57:0d:47:af:c3:2f:9f:87:46:a7:eb:26:5a:0f:56:63:
+ b5:62:60:6e:00:fb:e3:27:11:22:e7:fe:99:8f:34:f5:b9:e8:
+ c3:91:72:bd:d8:c3:1e:b9:2e:f2:91:44:51:d0:57:cd:0c:34:
+ d5:48:21:bf:db:13:f1:66:25:43:52:d2:70:22:36:cd:9f:c4:
+ 1c:75:20:ad:63:72:63:06:0f:0e:27:ce:d2:6a:0d:bc:b5:39:
+ 1a:e9:d1:76:7a:d1:5c:e4:e7:49:49:2d:55:37:68:f0:1a:3a:
+ 98:3e:54:17:87:54:e9:a6:27:50:89:7b:20:2f:3f:ff:bf:a1:
+ 8b:4a:47:98:ff:2b:7b:49:3e:c3:29:46:60:18:42:ab:33:29:
+ ba:c0:29:b9:13:89:d3:88:8a:39:41:3b:c9:fd:a6:ed:1f:f4:
+ 60:63:df:d2:2d:55:01:8b
+SHA1 Fingerprint=AD:98:F9:F3:E4:7D:75:3B:65:D4:82:B3:A4:52:17:BB:6E:F5:E4:38
diff --git a/apex/ca-certificates/files/e7dd1bc4.0 b/apex/ca-certificates/files/e7dd1bc4.0
new file mode 100644
index 0000000..210e2dc
--- /dev/null
+++ b/apex/ca-certificates/files/e7dd1bc4.0
@@ -0,0 +1,121 @@
+-----BEGIN CERTIFICATE-----
+MIIFbDCCA1SgAwIBAgIUVBa/O345lXGN0aoApYYNK496BU4wDQYJKoZIhvcNAQEL
+BQAwTjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwi
+Q29tbVNjb3BlIFB1YmxpYyBUcnVzdCBSU0EgUm9vdC0wMjAeFw0yMTA0MjgxNzE2
+NDNaFw00NjA0MjgxNzE2NDJaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21t
+U2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgUlNBIFJvb3Qt
+MDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDh+g77aAASyE3VrCLE
+NQE7xVTlWXZjpX/rwcRqmL0yjReA61260WI9JSMZNRTpf4mnG2I81lDnNJUDMrG0
+kyI9p+Kx7eZ7Ti6Hmw0zdQreqjXnfuU2mKKuJZ6VszKWpCtYHu8//mI0SFHRtI1C
+rWDaSWqVcN3SAOLMV2MCe5bdSZdbkk6V0/nLKR8YSvgBKtJjCW4k6YnS5cciTNxz
+hkcAqg2Ijq6FfUrpuzNPDlJwnZXjfG2WWy09X6GDRl224yW4fKcZgBzqZUPckXk2
+LHR88mcGyYnJ27/aaL8j7dxrrSiDeS/sOKUNNwFnJ5rpM9kzXzehxfCrPfp4sOcs
+n/Y+n2Dg70jpkEUeBVF4GiwSLFworA2iI540jwXmojPOEXcT1A6kHkIfhs1w/tku
+FT0du7jyU1fbzMZ0KZwYszZ1OC4PVKH4kh+Jlk+71O6d6Ts2QrUKOyrUZHk2EOH5
+kQMreyBUzQ0ZGshBMjTRsJnhkB4BQDa1t/qp5Xd1pCKBXbCL5CcSD1SIxtuFdOa3
+wNemKfrb3vOTlycEVS8KbzfFPROvCgCpLIscgSjX74Yxqa7ybrjKaixUR9gqiC6v
+wQcQeKwRoi9C8DfF8rhW3Q5iLc4tVn5V8qdE9isy9COoR+jUKgF4z2rDN6ieZdIs
+5fq6M8EGRPbmz6UNp2YINIos8wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G
+A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUR9DnsSL/nSz12Vdgs7GxcJXvYXowDQYJ
+KoZIhvcNAQELBQADggIBAIZpsU0v6Z9PIpNojuQhmaPORVMbc0RTAIFhzTHjCLqB
+KCh6krm2qMhDnscTJk3C2OVVnJJdUNjCK9v+5qiXz1I6JMNlZFxHMaNlNRPDk7n3
++VGXu6TwYofF1gbTl4MgqX67tiHCpQ2EAOHyJxCDut0DgdXdaMNmEMjRdrSzbyme
+APnCKfWxkxlSaRosTKCL4BWaMS/TiJVZbuXEs1DIFAhKm4sTg7GkcrI7djNB3Nyq
+pgdvHSQSn8h2vS/ZjvQs7rfSOBAkNlEv41xdgSGn2rtO/+YHqP65DSdsu3BaVXoT
+6fEqSWnHX4dXTEN5bTpl6TBcQe7rd6VzEojov32u5cSoHw2OHG1QAk8mGEPej1WF
+sQs3BWDJVTkSBKEqz3EWnzZRSb9wO55nnPt7eck5HHisd5FUmrh1CoFSl+NmYWvt
+PjgelmFV4ZFUjO2MJB+ByRCac5krFk5yAD9UG/iNuovnFNa2RU9g7Jauwy8CTl2d
+lklyALKrdVwPaFsdZcJfMw8eD/A7hvWwTruc9+olBdytoptLFwG+Qt81IR2tq670
+v64fG9PiO/yzcnMcmyiQiRM9HcEARwmWmjgb3bHPDcK0RPOWlc4yOo80nOAXx17O
+rg3bhzjlP1v9mxnhMUF6cKojawHhRUzNlM47ni3niAIi9G7oyOzWPPO5std3eqx7
+-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 54:16:bf:3b:7e:39:95:71:8d:d1:aa:00:a5:86:0d:2b:8f:7a:05:4e
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, O=CommScope, CN=CommScope Public Trust RSA Root-02
+ Validity
+ Not Before: Apr 28 17:16:43 2021 GMT
+ Not After : Apr 28 17:16:42 2046 GMT
+ Subject: C=US, O=CommScope, CN=CommScope Public Trust RSA Root-02
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (4096 bit)
+ Modulus:
+ 00:e1:fa:0e:fb:68:00:12:c8:4d:d5:ac:22:c4:35:
+ 01:3b:c5:54:e5:59:76:63:a5:7f:eb:c1:c4:6a:98:
+ bd:32:8d:17:80:eb:5d:ba:d1:62:3d:25:23:19:35:
+ 14:e9:7f:89:a7:1b:62:3c:d6:50:e7:34:95:03:32:
+ b1:b4:93:22:3d:a7:e2:b1:ed:e6:7b:4e:2e:87:9b:
+ 0d:33:75:0a:de:aa:35:e7:7e:e5:36:98:a2:ae:25:
+ 9e:95:b3:32:96:a4:2b:58:1e:ef:3f:fe:62:34:48:
+ 51:d1:b4:8d:42:ad:60:da:49:6a:95:70:dd:d2:00:
+ e2:cc:57:63:02:7b:96:dd:49:97:5b:92:4e:95:d3:
+ f9:cb:29:1f:18:4a:f8:01:2a:d2:63:09:6e:24:e9:
+ 89:d2:e5:c7:22:4c:dc:73:86:47:00:aa:0d:88:8e:
+ ae:85:7d:4a:e9:bb:33:4f:0e:52:70:9d:95:e3:7c:
+ 6d:96:5b:2d:3d:5f:a1:83:46:5d:b6:e3:25:b8:7c:
+ a7:19:80:1c:ea:65:43:dc:91:79:36:2c:74:7c:f2:
+ 67:06:c9:89:c9:db:bf:da:68:bf:23:ed:dc:6b:ad:
+ 28:83:79:2f:ec:38:a5:0d:37:01:67:27:9a:e9:33:
+ d9:33:5f:37:a1:c5:f0:ab:3d:fa:78:b0:e7:2c:9f:
+ f6:3e:9f:60:e0:ef:48:e9:90:45:1e:05:51:78:1a:
+ 2c:12:2c:5c:28:ac:0d:a2:23:9e:34:8f:05:e6:a2:
+ 33:ce:11:77:13:d4:0e:a4:1e:42:1f:86:cd:70:fe:
+ d9:2e:15:3d:1d:bb:b8:f2:53:57:db:cc:c6:74:29:
+ 9c:18:b3:36:75:38:2e:0f:54:a1:f8:92:1f:89:96:
+ 4f:bb:d4:ee:9d:e9:3b:36:42:b5:0a:3b:2a:d4:64:
+ 79:36:10:e1:f9:91:03:2b:7b:20:54:cd:0d:19:1a:
+ c8:41:32:34:d1:b0:99:e1:90:1e:01:40:36:b5:b7:
+ fa:a9:e5:77:75:a4:22:81:5d:b0:8b:e4:27:12:0f:
+ 54:88:c6:db:85:74:e6:b7:c0:d7:a6:29:fa:db:de:
+ f3:93:97:27:04:55:2f:0a:6f:37:c5:3d:13:af:0a:
+ 00:a9:2c:8b:1c:81:28:d7:ef:86:31:a9:ae:f2:6e:
+ b8:ca:6a:2c:54:47:d8:2a:88:2e:af:c1:07:10:78:
+ ac:11:a2:2f:42:f0:37:c5:f2:b8:56:dd:0e:62:2d:
+ ce:2d:56:7e:55:f2:a7:44:f6:2b:32:f4:23:a8:47:
+ e8:d4:2a:01:78:cf:6a:c3:37:a8:9e:65:d2:2c:e5:
+ fa:ba:33:c1:06:44:f6:e6:cf:a5:0d:a7:66:08:34:
+ 8a:2c:f3
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ 47:D0:E7:B1:22:FF:9D:2C:F5:D9:57:60:B3:B1:B1:70:95:EF:61:7A
+ Signature Algorithm: sha256WithRSAEncryption
+ Signature Value:
+ 86:69:b1:4d:2f:e9:9f:4f:22:93:68:8e:e4:21:99:a3:ce:45:
+ 53:1b:73:44:53:00:81:61:cd:31:e3:08:ba:81:28:28:7a:92:
+ b9:b6:a8:c8:43:9e:c7:13:26:4d:c2:d8:e5:55:9c:92:5d:50:
+ d8:c2:2b:db:fe:e6:a8:97:cf:52:3a:24:c3:65:64:5c:47:31:
+ a3:65:35:13:c3:93:b9:f7:f9:51:97:bb:a4:f0:62:87:c5:d6:
+ 06:d3:97:83:20:a9:7e:bb:b6:21:c2:a5:0d:84:00:e1:f2:27:
+ 10:83:ba:dd:03:81:d5:dd:68:c3:66:10:c8:d1:76:b4:b3:6f:
+ 29:9e:00:f9:c2:29:f5:b1:93:19:52:69:1a:2c:4c:a0:8b:e0:
+ 15:9a:31:2f:d3:88:95:59:6e:e5:c4:b3:50:c8:14:08:4a:9b:
+ 8b:13:83:b1:a4:72:b2:3b:76:33:41:dc:dc:aa:a6:07:6f:1d:
+ 24:12:9f:c8:76:bd:2f:d9:8e:f4:2c:ee:b7:d2:38:10:24:36:
+ 51:2f:e3:5c:5d:81:21:a7:da:bb:4e:ff:e6:07:a8:fe:b9:0d:
+ 27:6c:bb:70:5a:55:7a:13:e9:f1:2a:49:69:c7:5f:87:57:4c:
+ 43:79:6d:3a:65:e9:30:5c:41:ee:eb:77:a5:73:12:88:e8:bf:
+ 7d:ae:e5:c4:a8:1f:0d:8e:1c:6d:50:02:4f:26:18:43:de:8f:
+ 55:85:b1:0b:37:05:60:c9:55:39:12:04:a1:2a:cf:71:16:9f:
+ 36:51:49:bf:70:3b:9e:67:9c:fb:7b:79:c9:39:1c:78:ac:77:
+ 91:54:9a:b8:75:0a:81:52:97:e3:66:61:6b:ed:3e:38:1e:96:
+ 61:55:e1:91:54:8c:ed:8c:24:1f:81:c9:10:9a:73:99:2b:16:
+ 4e:72:00:3f:54:1b:f8:8d:ba:8b:e7:14:d6:b6:45:4f:60:ec:
+ 96:ae:c3:2f:02:4e:5d:9d:96:49:72:00:b2:ab:75:5c:0f:68:
+ 5b:1d:65:c2:5f:33:0f:1e:0f:f0:3b:86:f5:b0:4e:bb:9c:f7:
+ ea:25:05:dc:ad:a2:9b:4b:17:01:be:42:df:35:21:1d:ad:ab:
+ ae:f4:bf:ae:1f:1b:d3:e2:3b:fc:b3:72:73:1c:9b:28:90:89:
+ 13:3d:1d:c1:00:47:09:96:9a:38:1b:dd:b1:cf:0d:c2:b4:44:
+ f3:96:95:ce:32:3a:8f:34:9c:e0:17:c7:5e:ce:ae:0d:db:87:
+ 38:e5:3f:5b:fd:9b:19:e1:31:41:7a:70:aa:23:6b:01:e1:45:
+ 4c:cd:94:ce:3b:9e:2d:e7:88:02:22:f4:6e:e8:c8:ec:d6:3c:
+ f3:b9:b2:d7:77:7a:ac:7b
+SHA1 Fingerprint=EA:B0:E2:52:1B:89:93:4C:11:68:F2:D8:9A:AC:22:4C:A3:8A:57:AE
diff --git a/apex/ca-certificates/soong/Android.bp b/apex/ca-certificates/soong/Android.bp
deleted file mode 100644
index e305794..0000000
--- a/apex/ca-certificates/soong/Android.bp
+++ /dev/null
@@ -1,26 +0,0 @@
-// *** THIS PACKAGE HAS SPECIAL LICENSING CONDITIONS. PLEASE
-// CONSULT THE OWNERS AND opensource-licensing@google.com BEFORE
-// DEPENDING ON IT IN YOUR PROJECT. ***
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "system_ca-certificates_license"
- // to get the below license kinds:
- // legacy_by_exception_only (by exception only)
- default_applicable_licenses: ["apex_ca-certificates_license"],
-}
-
-// This is a temporary solution for adding certificates to the apex.
-bootstrap_go_package {
- name: "soong-ca-certificates-apex",
- pkgPath: "android/soong/external/conscrypt/apex/ca-certificates",
- deps: [
- "soong-android",
- "soong-etc",
- "soong-phony",
- ],
- srcs: [
- "ca_certificates_apex.go",
- ],
- pluginFor: ["soong_build"],
-}
diff --git a/apex/ca-certificates/soong/ca_certificates_apex.go b/apex/ca-certificates/soong/ca_certificates_apex.go
deleted file mode 100644
index 768485b..0000000
--- a/apex/ca-certificates/soong/ca_certificates_apex.go
+++ /dev/null
@@ -1,70 +0,0 @@
-package ca_certificates_apex
-
-import (
- "path"
- "path/filepath"
-
- "github.com/google/blueprint/proptools"
-
- "android/soong/android"
- "android/soong/etc"
- "android/soong/phony"
-)
-
-func init() {
- android.RegisterModuleType("ca_certificates_apex", caCertificatesApexFactory)
-}
-
-type caCertificatesProperties struct {
- Src_dir *string
- Dest_dir *string
- Module_name_prefix *string
-}
-
-func caCertificatesLoadHook(
- ctx android.LoadHookContext, factory android.ModuleFactory, c *caCertificatesProperties) {
- // Find all files in src_dir.
- srcs, err := ctx.GlobWithDeps(path.Join(ctx.ModuleDir(), *c.Src_dir, "*"), nil)
- if err != nil || len(srcs) == 0 {
- ctx.PropertyErrorf("src_dir", "cannot find files to install")
- return
- }
-
- // Scan through the found files to create a prebuilt_etc module for each of them.
- requiredModuleNames := make([]string, len(srcs))
- for i, src := range srcs {
- etcProps := struct {
- Name *string
- Src *string
- Sub_dir *string
- Filename *string
- }{}
- filename := filepath.Base(src)
- moduleName := *c.Module_name_prefix + filename
- etcProps.Name = proptools.StringPtr(moduleName)
- etcProps.Src = proptools.StringPtr(path.Join(*c.Src_dir, filename))
- etcProps.Sub_dir = c.Dest_dir
- etcProps.Filename = proptools.StringPtr(filename)
- ctx.CreateModule(factory, &etcProps)
-
- // Add it to the required module list of the parent phony rule.
- requiredModuleNames[i] = moduleName
- }
-
- phonyProps := struct {
- Required []string
- }{}
- phonyProps.Required = requiredModuleNames
- ctx.AppendProperties(&phonyProps)
-}
-
-func caCertificatesApexFactory() android.Module {
- p := phony.PhonyFactory()
- c := &caCertificatesProperties{}
- android.AddLoadHook(p, func(ctx android.LoadHookContext) {
- caCertificatesLoadHook(ctx, etc.PrebuiltEtcCaCertsFactory, c)
- })
- p.AddProperties(c)
-
- return p
-}
diff --git a/apex/tests/AndroidManifest.xml b/apex/tests/AndroidManifest.xml
index 7ec61f8..8f932eb 100644
--- a/apex/tests/AndroidManifest.xml
+++ b/apex/tests/AndroidManifest.xml
@@ -18,7 +18,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.conscrypt.mts">
- <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29" />
+ <uses-sdk android:minSdkVersion="30" android:targetSdkVersion="30" />
<uses-permission android:name="android.permission.INTERNET" />
<application>
diff --git a/apex/tests/TEST_MAPPING b/apex/tests/TEST_MAPPING
index 76428bd..4cd9b53 100644
--- a/apex/tests/TEST_MAPPING
+++ b/apex/tests/TEST_MAPPING
@@ -1,4 +1,49 @@
{
+ "conscrypt-mainline-presubmit": [
+ {
+ "name": "MtsConscryptTestCases",
+ "options": [
+ {
+ "exclude-filter": "org.apache.harmony.crypto.tests.javax.crypto.func.KeyAgreementFunctionalTest#test_KeyAgreement"
+ },
+ {
+ "exclude-filter": "com.android.org.conscrypt.java.security.AlgorithmParameterGeneratorTestDH#testAlgorithmParameterGenerator"
+ },
+ {
+ "exclude-filter": "org.apache.harmony.crypto.tests.javax.crypto.KeyAgreementTest#test_generateSecretLjava_lang_String"
+ },
+ {
+ "exclude-filter": "org.apache.harmony.tests.javax.net.ssl.TrustManagerFactory1Test#test_initLjavax_net_ssl_ManagerFactoryParameters"
+ },
+ {
+ "exclude-filter": "com.android.org.conscrypt.java.security.SignatureTest#test_getInstance"
+ },
+ {
+ "exclude-filter": "com.android.org.conscrypt.javax.crypto.CipherTest#test_PBKDF2WITHHMACSHA1_SKFactory_and_PBEAESCBC_Cipher_noIV"
+ }
+ ]
+ },
+ {
+ "name": "MtsConscryptFdSocketTestCases",
+ "options": [
+ {
+ "exclude-filter": "org.apache.harmony.crypto.tests.javax.crypto.func.KeyAgreementFunctionalTest#test_KeyAgreement"
+ },
+ {
+ "exclude-filter": "com.android.org.conscrypt.java.security.AlgorithmParameterGeneratorTestDH#testAlgorithmParameterGenerator"
+ },
+ {
+ "exclude-filter": "org.apache.harmony.crypto.tests.javax.crypto.KeyAgreementTest#test_generateSecretLjava_lang_String"
+ },
+ {
+ "exclude-filter": "org.apache.harmony.tests.javax.net.ssl.TrustManagerFactory1Test#test_initLjavax_net_ssl_ManagerFactoryParameters"
+ },
+ {
+ "exclude-filter": "com.android.org.conscrypt.javax.crypto.CipherTest#test_PBKDF2WITHHMACSHA1_SKFactory_and_PBEAESCBC_Cipher_noIV"
+ }
+ ]
+ }
+ ],
"mainline-presubmit": [
{
"name": "MtsConscryptTestCases[com.google.android.conscrypt.apex]",
diff --git a/common/src/jni/main/cpp/conscrypt/native_crypto.cc b/common/src/jni/main/cpp/conscrypt/native_crypto.cc
index 54625f5..784b706 100644
--- a/common/src/jni/main/cpp/conscrypt/native_crypto.cc
+++ b/common/src/jni/main/cpp/conscrypt/native_crypto.cc
@@ -4437,16 +4437,31 @@
return resultArray.release();
}
+static void NativeCrypto_CMAC_Reset(JNIEnv* env, jclass, jobject cmacCtxRef) {
+ CHECK_ERROR_QUEUE_ON_RETURN;
+ CMAC_CTX* cmacCtx = fromContextObject<CMAC_CTX>(env, cmacCtxRef);
+ JNI_TRACE("CMAC_Reset(%p)", cmacCtx);
+
+ if (cmacCtx == nullptr) {
+ return;
+ }
+
+ if (!CMAC_Reset(cmacCtx)) {
+ JNI_TRACE("CMAC_Reset(%p) => threw exception", cmacCtx);
+ conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "CMAC_Reset");
+ return;
+ }
+}
+
static jlong NativeCrypto_HMAC_CTX_new(JNIEnv* env, jclass) {
CHECK_ERROR_QUEUE_ON_RETURN;
JNI_TRACE("HMAC_CTX_new");
- auto hmacCtx = new HMAC_CTX;
+ auto hmacCtx = HMAC_CTX_new();
if (hmacCtx == nullptr) {
conscrypt::jniutil::throwOutOfMemory(env, "Unable to allocate HMAC_CTX");
return 0;
}
- HMAC_CTX_init(hmacCtx);
return reinterpret_cast<jlong>(hmacCtx);
}
@@ -4458,8 +4473,7 @@
conscrypt::jniutil::throwNullPointerException(env, "hmacCtx == null");
return;
}
- HMAC_CTX_cleanup(hmacCtx);
- delete hmacCtx;
+ HMAC_CTX_free(hmacCtx);
}
static void NativeCrypto_HMAC_Init_ex(JNIEnv* env, jclass, jobject hmacCtxRef, jbyteArray keyArray,
@@ -4566,6 +4580,24 @@
return resultArray.release();
}
+static void NativeCrypto_HMAC_Reset(JNIEnv* env, jclass, jobject hmacCtxRef) {
+ CHECK_ERROR_QUEUE_ON_RETURN;
+ HMAC_CTX* hmacCtx = fromContextObject<HMAC_CTX>(env, hmacCtxRef);
+ JNI_TRACE("HMAC_Reset(%p)", hmacCtx);
+
+ if (hmacCtx == nullptr) {
+ return;
+ }
+
+ // HMAC_Init_ex with all nulls will reuse the existing key. This is slightly
+ // more efficient than re-initializing the context with the key again.
+ if (!HMAC_Init_ex(hmacCtx, /*key=*/nullptr, /*key_len=*/0, /*md=*/nullptr, /*impl=*/nullptr)) {
+ JNI_TRACE("HMAC_Reset(%p) => threw exception", hmacCtx);
+ conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "HMAC_Init_ex");
+ return;
+ }
+}
+
static void NativeCrypto_RAND_bytes(JNIEnv* env, jclass, jbyteArray output) {
CHECK_ERROR_QUEUE_ON_RETURN;
JNI_TRACE("NativeCrypto_RAND_bytes(%p)", output);
@@ -10812,6 +10844,50 @@
return FIPS_mode();
}
+/**
+ * Scrypt support
+ */
+
+static jbyteArray NativeCrypto_Scrypt_generate_key(JNIEnv* env, jclass, jbyteArray password, jbyteArray salt,
+ jint n, jint r, jint p, jint key_len) {
+ CHECK_ERROR_QUEUE_ON_RETURN;
+ JNI_TRACE("Scrypt_generate_key(%p, %p, %d, %d, %d, %d)", password, salt, n, r, p, key_len);
+
+ if (password == nullptr) {
+ conscrypt::jniutil::throwNullPointerException(env, "password == null");
+ JNI_TRACE("Scrypt_generate_key() => password == null");
+ return nullptr;
+ }
+ if (salt == nullptr) {
+ conscrypt::jniutil::throwNullPointerException(env, "salt == null");
+ JNI_TRACE("Scrypt_generate_key() => salt == null");
+ return nullptr;
+ }
+
+ jbyteArray key_bytes = env->NewByteArray(static_cast<jsize>(key_len));
+ ScopedByteArrayRW out_key(env, key_bytes);
+ if (out_key.get() == nullptr) {
+ conscrypt::jniutil::throwNullPointerException(env, "out_key == null");
+ JNI_TRACE("Scrypt_generate_key() => out_key == null");
+ return nullptr;
+ }
+
+ size_t memory_limit = 1u << 29;
+ ScopedByteArrayRO password_bytes(env, password);
+ ScopedByteArrayRO salt_bytes(env, salt);
+
+ int result = EVP_PBE_scrypt(reinterpret_cast<const char*>(password_bytes.get()), password_bytes.size(),
+ reinterpret_cast<const uint8_t*>(salt_bytes.get()), salt_bytes.size(),
+ n, r, p, memory_limit,
+ reinterpret_cast<uint8_t*>(out_key.get()), key_len);
+
+ if (result <= 0) {
+ conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "Scrypt_generate_key");
+ return nullptr;
+ }
+ return key_bytes;
+}
+
// TESTING METHODS BEGIN
static int NativeCrypto_BIO_read(JNIEnv* env, jclass, jlong bioRef, jbyteArray outputJavaBytes) {
@@ -10989,6 +11065,7 @@
CONSCRYPT_NATIVE_METHOD(CMAC_Update, "(" REF_CMAC_CTX "[BII)V"),
CONSCRYPT_NATIVE_METHOD(CMAC_UpdateDirect, "(" REF_CMAC_CTX "JI)V"),
CONSCRYPT_NATIVE_METHOD(CMAC_Final, "(" REF_CMAC_CTX ")[B"),
+ CONSCRYPT_NATIVE_METHOD(CMAC_Reset, "(" REF_CMAC_CTX ")V"),
CONSCRYPT_NATIVE_METHOD(EVP_PKEY_new_RSA, "([B[B[B[B[B[B[B[B)J"),
CONSCRYPT_NATIVE_METHOD(EVP_PKEY_new_EC_KEY, "(" REF_EC_GROUP REF_EC_POINT "[B)J"),
CONSCRYPT_NATIVE_METHOD(EVP_PKEY_type, "(" REF_EVP_PKEY ")I"),
@@ -11109,6 +11186,7 @@
CONSCRYPT_NATIVE_METHOD(HMAC_Update, "(" REF_HMAC_CTX "[BII)V"),
CONSCRYPT_NATIVE_METHOD(HMAC_UpdateDirect, "(" REF_HMAC_CTX "JI)V"),
CONSCRYPT_NATIVE_METHOD(HMAC_Final, "(" REF_HMAC_CTX ")[B"),
+ CONSCRYPT_NATIVE_METHOD(HMAC_Reset, "(" REF_HMAC_CTX ")V"),
CONSCRYPT_NATIVE_METHOD(RAND_bytes, "([B)V"),
CONSCRYPT_NATIVE_METHOD(create_BIO_InputStream, ("(" REF_BIO_IN_STREAM "Z)J")),
CONSCRYPT_NATIVE_METHOD(create_BIO_OutputStream, "(Ljava/io/OutputStream;)J"),
@@ -11287,6 +11365,7 @@
CONSCRYPT_NATIVE_METHOD(ENGINE_SSL_force_read, "(J" REF_SSL SSL_CALLBACKS ")V"),
CONSCRYPT_NATIVE_METHOD(ENGINE_SSL_shutdown, "(J" REF_SSL SSL_CALLBACKS ")V"),
CONSCRYPT_NATIVE_METHOD(usesBoringSsl_FIPS_mode, "()Z"),
+ CONSCRYPT_NATIVE_METHOD(Scrypt_generate_key, "([B[BIIII)[B"),
// Used for testing only.
CONSCRYPT_NATIVE_METHOD(BIO_read, "(J[B)I"),
diff --git a/common/src/main/java/org/conscrypt/ArrayUtils.java b/common/src/main/java/org/conscrypt/ArrayUtils.java
index 99a1eb5..8bb148e 100644
--- a/common/src/main/java/org/conscrypt/ArrayUtils.java
+++ b/common/src/main/java/org/conscrypt/ArrayUtils.java
@@ -73,4 +73,11 @@
}
return result;
}
+
+ /**
+ * Checks if given array is null or has zero elements.
+ */
+ public static <T> boolean isEmpty(T[] array) {
+ return array == null || array.length == 0;
+ }
}
diff --git a/common/src/main/java/org/conscrypt/ByteArray.java b/common/src/main/java/org/conscrypt/ByteArray.java
index bfc544f..3e97eb5 100644
--- a/common/src/main/java/org/conscrypt/ByteArray.java
+++ b/common/src/main/java/org/conscrypt/ByteArray.java
@@ -21,11 +21,12 @@
/**
* Byte array wrapper for hashtable use. Implements equals() and hashCode().
*/
-final class ByteArray {
+@Internal
+public final class ByteArray {
private final byte[] bytes;
private final int hashCode;
- ByteArray(byte[] bytes) {
+ public ByteArray(byte[] bytes) {
this.bytes = bytes;
this.hashCode = Arrays.hashCode(bytes);
}
@@ -37,6 +38,9 @@
@Override
public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
if (!(o instanceof ByteArray)) {
return false;
}
diff --git a/common/src/main/java/org/conscrypt/ConscryptEngine.java b/common/src/main/java/org/conscrypt/ConscryptEngine.java
index bf3d1c8..a58aa73 100644
--- a/common/src/main/java/org/conscrypt/ConscryptEngine.java
+++ b/common/src/main/java/org/conscrypt/ConscryptEngine.java
@@ -441,13 +441,6 @@
handshake();
releaseResources = false;
} catch (IOException e) {
- // Write CCS errors to EventLog
- String message = e.getMessage();
- // Must match error reason string of SSL_R_UNEXPECTED_CCS (in ssl/ssl_err.c)
- if (message.contains("unexpected CCS")) {
- String logMessage = String.format("ssl_unexpected_ccs: host=%s", getPeerHost());
- Platform.logEvent(logMessage);
- }
closeAll();
throw SSLUtils.toSSLHandshakeException(e);
} finally {
diff --git a/common/src/main/java/org/conscrypt/ConscryptFileDescriptorSocket.java b/common/src/main/java/org/conscrypt/ConscryptFileDescriptorSocket.java
index be0ec97..eeba2bb 100644
--- a/common/src/main/java/org/conscrypt/ConscryptFileDescriptorSocket.java
+++ b/common/src/main/java/org/conscrypt/ConscryptFileDescriptorSocket.java
@@ -246,16 +246,6 @@
return;
}
}
-
- // Write CCS errors to EventLog
- String message = e.getMessage();
- // Must match error string of SSL_R_UNEXPECTED_CCS
- if (message.contains("unexpected CCS")) {
- String logMessage =
- String.format("ssl_unexpected_ccs: host=%s", getHostnameOrIP());
- Platform.logEvent(logMessage);
- }
-
throw e;
}
diff --git a/common/src/main/java/org/conscrypt/NativeCrypto.java b/common/src/main/java/org/conscrypt/NativeCrypto.java
index 7bb509a..d017f9e 100644
--- a/common/src/main/java/org/conscrypt/NativeCrypto.java
+++ b/common/src/main/java/org/conscrypt/NativeCrypto.java
@@ -369,6 +369,8 @@
static native byte[] CMAC_Final(NativeRef.CMAC_CTX ctx);
+ static native void CMAC_Reset(NativeRef.CMAC_CTX ctx);
+
// --- HMAC functions ------------------------------------------------------
static native long HMAC_CTX_new();
@@ -383,6 +385,8 @@
static native byte[] HMAC_Final(NativeRef.HMAC_CTX ctx);
+ static native void HMAC_Reset(NativeRef.HMAC_CTX ctx);
+
// --- HPKE functions ------------------------------------------------------
static native byte[] EVP_HPKE_CTX_export(
NativeRef.EVP_HPKE_CTX ctx, byte[] exporterCtx, int length);
@@ -529,7 +533,7 @@
static native byte[] X509_get_serialNumber(long x509ctx, OpenSSLX509Certificate holder);
static native void X509_verify(long x509ctx, OpenSSLX509Certificate holder, NativeRef.EVP_PKEY pkeyCtx)
- throws BadPaddingException;
+ throws BadPaddingException, IllegalBlockSizeException;
static native byte[] get_X509_tbs_cert(long x509ctx, OpenSSLX509Certificate holder);
@@ -781,8 +785,8 @@
// --- SSL handling --------------------------------------------------------
static final String OBSOLETE_PROTOCOL_SSLV3 = "SSLv3";
- private static final String DEPRECATED_PROTOCOL_TLSV1 = "TLSv1";
- private static final String DEPRECATED_PROTOCOL_TLSV1_1 = "TLSv1.1";
+ static final String DEPRECATED_PROTOCOL_TLSV1 = "TLSv1";
+ static final String DEPRECATED_PROTOCOL_TLSV1_1 = "TLSv1.1";
private static final String SUPPORTED_PROTOCOL_TLSV1_2 = "TLSv1.2";
static final String SUPPORTED_PROTOCOL_TLSV1_3 = "TLSv1.3";
@@ -1022,6 +1026,11 @@
DEPRECATED_PROTOCOL_TLSV1_1,
};
+ private static final String[] SUPPORTED_PROTOCOLS_TLSV1 = Platform.isTlsV1Supported()
+ ? new String[] {
+ DEPRECATED_PROTOCOL_TLSV1,
+ DEPRECATED_PROTOCOL_TLSV1_1,
+ } : new String[0];
/** Protocols to enable by default when "TLSv1.3" is requested. */
static final String[] TLSV13_PROTOCOLS = ArrayUtils.concatValues(
@@ -1045,12 +1054,13 @@
static final String[] TLSV1_PROTOCOLS = TLSV11_PROTOCOLS;
static final String[] DEFAULT_PROTOCOLS = TLSV13_PROTOCOLS;
- private static final String[] SUPPORTED_PROTOCOLS = new String[] {
- DEPRECATED_PROTOCOL_TLSV1,
- DEPRECATED_PROTOCOL_TLSV1_1,
+
+ // If we ever get a new protocol go look for tests which are skipped using
+ // assumeTlsV11Enabled()
+ private static final String[] SUPPORTED_PROTOCOLS = ArrayUtils.concatValues(
+ SUPPORTED_PROTOCOLS_TLSV1,
SUPPORTED_PROTOCOL_TLSV1_2,
- SUPPORTED_PROTOCOL_TLSV1_3,
- };
+ SUPPORTED_PROTOCOL_TLSV1_3);
public static String[] getDefaultProtocols() {
if (Platform.isTlsV1Deprecated()) {
@@ -1127,11 +1137,7 @@
if (protocol == null) {
throw new IllegalArgumentException("protocols contains null");
}
- if (!protocol.equals(DEPRECATED_PROTOCOL_TLSV1)
- && !protocol.equals(DEPRECATED_PROTOCOL_TLSV1_1)
- && !protocol.equals(SUPPORTED_PROTOCOL_TLSV1_2)
- && !protocol.equals(SUPPORTED_PROTOCOL_TLSV1_3)
- && !protocol.equals(OBSOLETE_PROTOCOL_SSLV3)) {
+ if (!Arrays.asList(SUPPORTED_PROTOCOLS).contains(protocol)) {
throw new IllegalArgumentException("protocol " + protocol + " is not supported");
}
}
@@ -1506,6 +1512,11 @@
throws IOException;
/**
+ * Generates a key from a password and salt using Scrypt.
+ */
+ static native byte[] Scrypt_generate_key(byte[] password, byte[] salt, int n, int r, int p, int key_len);
+
+ /**
* Return {@code true} if BoringSSL has been built in FIPS mode.
*/
static native boolean usesBoringSsl_FIPS_mode();
diff --git a/common/src/main/java/org/conscrypt/NativeSsl.java b/common/src/main/java/org/conscrypt/NativeSsl.java
index 79369ca..7d260bc 100644
--- a/common/src/main/java/org/conscrypt/NativeSsl.java
+++ b/common/src/main/java/org/conscrypt/NativeSsl.java
@@ -308,8 +308,10 @@
if (parameters.getEnabledProtocols().length == 0 && parameters.isEnabledProtocolsFiltered) {
throw new SSLHandshakeException("No enabled protocols; "
- + NativeCrypto.OBSOLETE_PROTOCOL_SSLV3
- + " is no longer supported and was filtered from the list");
+ + NativeCrypto.OBSOLETE_PROTOCOL_SSLV3 + ", "
+ + NativeCrypto.DEPRECATED_PROTOCOL_TLSV1
+ + " and " + NativeCrypto.DEPRECATED_PROTOCOL_TLSV1_1
+ + " are no longer supported and were filtered from the list");
}
NativeCrypto.setEnabledProtocols(ssl, this, parameters.enabledProtocols);
NativeCrypto.setEnabledCipherSuites(
diff --git a/common/src/main/java/org/conscrypt/OpenSSLKey.java b/common/src/main/java/org/conscrypt/OpenSSLKey.java
index 6eb94f4..4249b8e 100644
--- a/common/src/main/java/org/conscrypt/OpenSSLKey.java
+++ b/common/src/main/java/org/conscrypt/OpenSSLKey.java
@@ -32,7 +32,8 @@
/**
* Represents a BoringSSL {@code EVP_PKEY}.
*/
-final class OpenSSLKey {
+@Internal
+public final class OpenSSLKey {
private final NativeRef.EVP_PKEY ctx;
private final boolean wrapped;
@@ -178,11 +179,6 @@
if (key instanceof OpenSSLKeyHolder) {
return ((OpenSSLKeyHolder) key).getOpenSSLKey();
}
-
- if ("RSA".equals(key.getAlgorithm())) {
- return Platform.wrapRsaKey(key);
- }
-
return null;
}
@@ -260,7 +256,7 @@
*
* @throws InvalidKeyException if parsing fails
*/
- static OpenSSLKey fromPublicKeyPemInputStream(InputStream is)
+ public static OpenSSLKey fromPublicKeyPemInputStream(InputStream is)
throws InvalidKeyException {
OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is, true);
try {
@@ -277,7 +273,7 @@
}
}
- PublicKey getPublicKey() throws NoSuchAlgorithmException {
+ public PublicKey getPublicKey() throws NoSuchAlgorithmException {
switch (NativeCrypto.EVP_PKEY_type(ctx)) {
case NativeConstants.EVP_PKEY_RSA:
return new OpenSSLRSAPublicKey(this);
diff --git a/common/src/main/java/org/conscrypt/OpenSSLMac.java b/common/src/main/java/org/conscrypt/OpenSSLMac.java
index 1bef88f..b8f5296 100644
--- a/common/src/main/java/org/conscrypt/OpenSSLMac.java
+++ b/common/src/main/java/org/conscrypt/OpenSSLMac.java
@@ -20,7 +20,6 @@
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
-import java.security.NoSuchAlgorithmException;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.MacSpi;
import javax.crypto.SecretKey;
@@ -31,11 +30,6 @@
@Internal
public abstract class OpenSSLMac extends MacSpi {
/**
- * The secret key used in this keyed MAC.
- */
- protected byte[] keyBytes;
-
- /**
* Holds the output size of the message digest.
*/
private final int size;
@@ -53,6 +47,11 @@
/**
* Creates and initializes the relevant BoringSSL *MAC context.
*/
+ protected abstract void initContext(byte[] keyBytes);
+
+ /**
+ * Resets the context for a new operation with the same key.
+ */
protected abstract void resetContext();
/**
@@ -76,13 +75,13 @@
throw new InvalidAlgorithmParameterException("unknown parameter type");
}
- keyBytes = key.getEncoded();
+ byte[] keyBytes = key.getEncoded();
if (keyBytes == null) {
throw new InvalidKeyException("key cannot be encoded");
}
try {
- resetContext();
+ initContext(keyBytes);
} catch (RuntimeException e) {
throw new InvalidKeyException("invalid key", e);
}
@@ -164,15 +163,19 @@
}
@Override
- protected void resetContext() {
+ protected void initContext(byte[] keyBytes) {
NativeRef.HMAC_CTX ctxLocal = new NativeRef.HMAC_CTX(NativeCrypto.HMAC_CTX_new());
- if (keyBytes != null) {
- NativeCrypto.HMAC_Init_ex(ctxLocal, keyBytes, evpMd);
- }
+ NativeCrypto.HMAC_Init_ex(ctxLocal, keyBytes, evpMd);
this.ctx = ctxLocal;
}
@Override
+ protected void resetContext() {
+ final NativeRef.HMAC_CTX ctxLocal = ctx;
+ NativeCrypto.HMAC_Reset(ctxLocal);
+ }
+
+ @Override
protected void engineUpdate(byte[] input, int offset, int len) {
final NativeRef.HMAC_CTX ctxLocal = ctx;
NativeCrypto.HMAC_Update(ctxLocal, input, offset, len);
@@ -236,15 +239,19 @@
}
@Override
- protected void resetContext() {
+ protected void initContext(byte[] keyBytes) {
NativeRef.CMAC_CTX ctxLocal = new NativeRef.CMAC_CTX(NativeCrypto.CMAC_CTX_new());
- if (keyBytes != null) {
- NativeCrypto.CMAC_Init(ctxLocal, keyBytes);
- }
+ NativeCrypto.CMAC_Init(ctxLocal, keyBytes);
this.ctx = ctxLocal;
}
@Override
+ protected void resetContext() {
+ final NativeRef.CMAC_CTX ctxLocal = ctx;
+ NativeCrypto.CMAC_Reset(ctxLocal);
+ }
+
+ @Override
protected void updateDirect(long ptr, int len) {
final NativeRef.CMAC_CTX ctxLocal = ctx;
NativeCrypto.CMAC_UpdateDirect(ctxLocal, ptr, len);
diff --git a/common/src/main/java/org/conscrypt/OpenSSLProvider.java b/common/src/main/java/org/conscrypt/OpenSSLProvider.java
index 99547dc..6fc30ff 100644
--- a/common/src/main/java/org/conscrypt/OpenSSLProvider.java
+++ b/common/src/main/java/org/conscrypt/OpenSSLProvider.java
@@ -217,6 +217,9 @@
/* == SecretKeyFactory == */
put("SecretKeyFactory.DESEDE", PREFIX + "DESEDESecretKeyFactory");
put("Alg.Alias.SecretKeyFactory.TDEA", "DESEDE");
+ put("SecretKeyFactory.SCRYPT", PREFIX + "ScryptSecretKeyFactory");
+ put("Alg.Alias.SecretKeyFactory.1.3.6.1.4.1.11591.4.11", "SCRYPT");
+ put("Alg.Alias.SecretKeyFactory.OID.1.3.6.1.4.1.11591.4.11", "SCRYPT");
/* == KeyAgreement == */
putECDHKeyAgreementImplClass("OpenSSLECDHKeyAgreement");
diff --git a/common/src/main/java/org/conscrypt/OpenSSLRSAPrivateKey.java b/common/src/main/java/org/conscrypt/OpenSSLRSAPrivateKey.java
index 6371bbb..c7e09fe 100644
--- a/common/src/main/java/org/conscrypt/OpenSSLRSAPrivateKey.java
+++ b/common/src/main/java/org/conscrypt/OpenSSLRSAPrivateKey.java
@@ -96,12 +96,7 @@
return new OpenSSLRSAPrivateKey(key, params);
}
- static OpenSSLKey wrapPlatformKey(RSAPrivateKey rsaPrivateKey)
- throws InvalidKeyException {
- OpenSSLKey wrapper = Platform.wrapRsaKey(rsaPrivateKey);
- if (wrapper != null) {
- return wrapper;
- }
+ static OpenSSLKey wrapPlatformKey(RSAPrivateKey rsaPrivateKey) {
return new OpenSSLKey(NativeCrypto.getRSAPrivateKeyWrapper(rsaPrivateKey, rsaPrivateKey
.getModulus().toByteArray()), true);
}
diff --git a/common/src/main/java/org/conscrypt/OpenSSLX509Certificate.java b/common/src/main/java/org/conscrypt/OpenSSLX509Certificate.java
index f5e5c5f..3998a25 100644
--- a/common/src/main/java/org/conscrypt/OpenSSLX509Certificate.java
+++ b/common/src/main/java/org/conscrypt/OpenSSLX509Certificate.java
@@ -48,6 +48,7 @@
import java.util.Set;
import java.util.TimeZone;
import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
import javax.security.auth.x500.X500Principal;
import org.conscrypt.OpenSSLX509CertificateFactory.ParsingException;
@@ -383,8 +384,8 @@
NativeCrypto.X509_verify(mContext, this, pkey.getNativeRef());
} catch (RuntimeException e) {
throw new CertificateException(e);
- } catch (BadPaddingException e) {
- throw new SignatureException();
+ } catch (BadPaddingException | IllegalBlockSizeException e) {
+ throw new SignatureException(e);
}
}
diff --git a/common/src/main/java/org/conscrypt/SSLParametersImpl.java b/common/src/main/java/org/conscrypt/SSLParametersImpl.java
index c38da79..846414b 100644
--- a/common/src/main/java/org/conscrypt/SSLParametersImpl.java
+++ b/common/src/main/java/org/conscrypt/SSLParametersImpl.java
@@ -27,6 +27,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.List;
import java.util.Set;
import javax.crypto.SecretKey;
import javax.net.ssl.KeyManager;
@@ -144,8 +145,20 @@
}
// initialize the list of cipher suites and protocols enabled by default
- enabledProtocols = NativeCrypto.checkEnabledProtocols(
- protocols == null ? NativeCrypto.getDefaultProtocols() : protocols).clone();
+ if (protocols == null) {
+ enabledProtocols = NativeCrypto.getDefaultProtocols().clone();
+ } else {
+ String[] filteredProtocols =
+ filterFromProtocols(protocols, Arrays.asList(!Platform.isTlsV1Filtered()
+ ? new String[0]
+ : new String[] {
+ NativeCrypto.OBSOLETE_PROTOCOL_SSLV3,
+ NativeCrypto.DEPRECATED_PROTOCOL_TLSV1,
+ NativeCrypto.DEPRECATED_PROTOCOL_TLSV1_1,
+ }));
+ isEnabledProtocolsFiltered = protocols.length != filteredProtocols.length;
+ enabledProtocols = NativeCrypto.checkEnabledProtocols(filteredProtocols).clone();
+ }
boolean x509CipherSuitesNeeded = (x509KeyManager != null) || (x509TrustManager != null);
boolean pskCipherSuitesNeeded = pskKeyManager != null;
enabledCipherSuites = getDefaultCipherSuites(
@@ -282,7 +295,13 @@
throw new IllegalArgumentException("protocols == null");
}
String[] filteredProtocols =
- filterFromProtocols(protocols, NativeCrypto.OBSOLETE_PROTOCOL_SSLV3);
+ filterFromProtocols(protocols, Arrays.asList(!Platform.isTlsV1Filtered()
+ ? new String[0]
+ : new String[] {
+ NativeCrypto.OBSOLETE_PROTOCOL_SSLV3,
+ NativeCrypto.DEPRECATED_PROTOCOL_TLSV1,
+ NativeCrypto.DEPRECATED_PROTOCOL_TLSV1_1,
+ }));
isEnabledProtocolsFiltered = protocols.length != filteredProtocols.length;
enabledProtocols = NativeCrypto.checkEnabledProtocols(filteredProtocols).clone();
}
@@ -430,14 +449,15 @@
* This filters {@code obsoleteProtocol} from the list of {@code protocols}
* down to help with app compatibility.
*/
- private static String[] filterFromProtocols(String[] protocols, String obsoleteProtocol) {
- if (protocols.length == 1 && obsoleteProtocol.equals(protocols[0])) {
+ private static String[] filterFromProtocols(String[] protocols,
+ List<String> obsoleteProtocols) {
+ if (protocols.length == 1 && obsoleteProtocols.contains(protocols[0])) {
return EMPTY_STRING_ARRAY;
}
ArrayList<String> newProtocols = new ArrayList<String>();
for (String protocol : protocols) {
- if (!obsoleteProtocol.equals(protocol)) {
+ if (!obsoleteProtocols.contains(protocol)) {
newProtocols.add(protocol);
}
}
diff --git a/common/src/main/java/org/conscrypt/ScryptKeySpec.java b/common/src/main/java/org/conscrypt/ScryptKeySpec.java
new file mode 100644
index 0000000..809459f
--- /dev/null
+++ b/common/src/main/java/org/conscrypt/ScryptKeySpec.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2022 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 org.conscrypt;
+
+import java.security.spec.KeySpec;
+
+/**
+ * Mirrors the <a
+ * href="https://javadoc.io/static/org.bouncycastle/bcprov-jdk15on/1.68/org/bouncycastle/jcajce/spec/ScryptKeySpec.html">class
+ * of the same name</a> from BouncyCastle.
+ */
+public class ScryptKeySpec implements KeySpec {
+ private final char[] password;
+ private final byte[] salt;
+ private final int costParameter;
+ private final int blockSize;
+ private final int parallelizationParameter;
+ private final int keyOutputBits;
+
+ public ScryptKeySpec(
+ char[] password,
+ byte[] salt,
+ int costParameter,
+ int blockSize,
+ int parallelizationParameter,
+ int keyOutputBits) {
+ this.password = password;
+ this.salt = salt;
+ this.costParameter = costParameter;
+ this.blockSize = blockSize;
+ this.parallelizationParameter = parallelizationParameter;
+ this.keyOutputBits = keyOutputBits;
+ }
+
+ public char[] getPassword() {
+ return password;
+ }
+
+ public byte[] getSalt() {
+ return salt;
+ }
+
+ public int getCostParameter() {
+ return costParameter;
+ }
+
+ public int getBlockSize() {
+ return blockSize;
+ }
+
+ public int getParallelizationParameter() {
+ return parallelizationParameter;
+ }
+
+ public int getKeyLength() {
+ return keyOutputBits;
+ }
+}
diff --git a/common/src/main/java/org/conscrypt/ScryptSecretKeyFactory.java b/common/src/main/java/org/conscrypt/ScryptSecretKeyFactory.java
new file mode 100644
index 0000000..9714bcf
--- /dev/null
+++ b/common/src/main/java/org/conscrypt/ScryptSecretKeyFactory.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2022 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 org.conscrypt;
+
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.InvalidKeyException;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactorySpi;
+
+@Internal
+public class ScryptSecretKeyFactory extends SecretKeyFactorySpi {
+
+ @Override
+ protected SecretKey engineGenerateSecret(KeySpec inKeySpec) throws InvalidKeySpecException {
+
+ char[] password;
+ byte[] salt;
+ int n, r, p, keyOutputBits;
+
+ if (inKeySpec instanceof ScryptKeySpec) {
+ ScryptKeySpec spec = (ScryptKeySpec) inKeySpec;
+ password = spec.getPassword();
+ salt = spec.getSalt();
+ n = spec.getCostParameter();
+ r = spec.getBlockSize();
+ p = spec.getParallelizationParameter();
+ keyOutputBits = spec.getKeyLength();
+ } else {
+ // Extract parameters from any `KeySpec` that has getters with the correct name. This
+ // allows, for example, code to use BouncyCastle's KeySpec with the Conscrypt provider.
+ try {
+ password = (char[]) getValue(inKeySpec, "getPassword");
+ salt = (byte[]) getValue(inKeySpec, "getSalt");
+ n = (int) getValue(inKeySpec, "getCostParameter");
+ r = (int) getValue(inKeySpec, "getBlockSize");
+ p = (int) getValue(inKeySpec, "getParallelizationParameter");
+ keyOutputBits = (int) getValue(inKeySpec, "getKeyLength");
+ } catch (Exception e) {
+ throw new InvalidKeySpecException("Not a valid scrypt KeySpec", e);
+ }
+ }
+
+ if (keyOutputBits % 8 != 0) {
+ throw new InvalidKeySpecException("Cannot produce fractional-byte outputs");
+ }
+
+ try {
+ return new ScryptKey(
+ NativeCrypto.Scrypt_generate_key(
+ new String(password).getBytes("UTF-8"),
+ salt, n, r, p, keyOutputBits / 8));
+ } catch (UnsupportedEncodingException e) {
+ // Impossible according to the Java docs: UTF-8 is always supported.
+ throw new IllegalStateException(e);
+ }
+ }
+
+ private Object getValue(KeySpec spec, String methodName)
+ throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+ Method method = spec.getClass().getMethod(methodName, (Class<?>[]) null);
+ return method.invoke(spec);
+ }
+
+ @Override
+ protected KeySpec engineGetKeySpec(
+ SecretKey secretKey, @SuppressWarnings("rawtypes") Class aClass)
+ throws InvalidKeySpecException {
+ if (secretKey == null) {
+ throw new InvalidKeySpecException("Null KeySpec");
+ }
+ throw new NotImplementedException();
+ }
+
+ @Override
+ protected SecretKey engineTranslateKey(SecretKey secretKey) throws InvalidKeyException {
+ if (secretKey == null) {
+ throw new InvalidKeyException("Null SecretKey");
+ }
+ throw new NotImplementedException();
+ }
+
+ private static class ScryptKey implements SecretKey {
+ private static final long serialVersionUID = 2024924811854189128L;
+ private final byte[] key;
+
+ public ScryptKey(byte[] key) {
+ this.key = key;
+ }
+
+ @Override
+ public String getAlgorithm() {
+ // Capitalised because BouncyCastle does it.
+ return "SCRYPT";
+ }
+
+ @Override
+ public String getFormat() {
+ return "RAW";
+ }
+
+ @Override
+ public byte[] getEncoded() {
+ return key;
+ }
+ }
+
+ private static class NotImplementedException extends RuntimeException {
+ NotImplementedException() {
+ super("Not implemented");
+ }
+ }
+}
diff --git a/common/src/main/java/org/conscrypt/ct/CTLogInfo.java b/common/src/main/java/org/conscrypt/ct/CTLogInfo.java
index c2e312a..997f0e9 100644
--- a/common/src/main/java/org/conscrypt/ct/CTLogInfo.java
+++ b/common/src/main/java/org/conscrypt/ct/CTLogInfo.java
@@ -32,12 +32,30 @@
*/
@Internal
public class CTLogInfo {
+ public static final int STATE_PENDING = 0;
+ public static final int STATE_QUALIFIED = 1;
+ public static final int STATE_USABLE = 2;
+ public static final int STATE_READONLY = 3;
+ public static final int STATE_RETIRED = 4;
+ public static final int STATE_REJECTED = 5;
+
private final byte[] logId;
private final PublicKey publicKey;
+ private final int state;
private final String description;
private final String url;
- public CTLogInfo(PublicKey publicKey, String description, String url) {
+ public CTLogInfo(PublicKey publicKey, int state, String description, String url) {
+ if (publicKey == null) {
+ throw new IllegalArgumentException("null publicKey");
+ }
+ if (description == null) {
+ throw new IllegalArgumentException("null description");
+ }
+ if (state < 0 || state > STATE_REJECTED) {
+ throw new IllegalArgumentException("invalid state value");
+ }
+
try {
this.logId = MessageDigest.getInstance("SHA-256")
.digest(publicKey.getEncoded());
@@ -47,6 +65,7 @@
}
this.publicKey = publicKey;
+ this.state = state;
this.description = description;
this.url = url;
}
@@ -70,6 +89,10 @@
return url;
}
+ public int getState() {
+ return state;
+ }
+
@Override
public boolean equals(Object other) {
if (this == other) {
@@ -80,18 +103,17 @@
}
CTLogInfo that = (CTLogInfo)other;
- return
- this.publicKey.equals(that.publicKey) &&
- this.description.equals(that.description) &&
- this.url.equals(that.url);
+ return this.state == that.state && this.description.equals(that.description)
+ && this.url.equals(that.url) && Arrays.equals(this.logId, that.logId);
}
@Override
public int hashCode() {
int hash = 1;
- hash = hash * 31 + publicKey.hashCode();
+ hash = hash * 31 + Arrays.hashCode(logId);
hash = hash * 31 + description.hashCode();
hash = hash * 31 + url.hashCode();
+ hash = hash * 31 + state;
return hash;
}
diff --git a/common/src/main/java/org/conscrypt/metrics/CipherSuite.java b/common/src/main/java/org/conscrypt/metrics/CipherSuite.java
index 12d7446..bab5354 100644
--- a/common/src/main/java/org/conscrypt/metrics/CipherSuite.java
+++ b/common/src/main/java/org/conscrypt/metrics/CipherSuite.java
@@ -63,7 +63,7 @@
TLS_CIPHER_FAILED(0xFFFF),
;
- final short id;
+ final int id;
public int getId() {
return this.id;
@@ -82,6 +82,6 @@
}
private CipherSuite(int id) {
- this.id = (short) id;
+ this.id = id;
}
}
\ No newline at end of file
diff --git a/common/src/main/java/org/conscrypt/metrics/Protocol.java b/common/src/main/java/org/conscrypt/metrics/Protocol.java
index 4762a4d..31ef714 100644
--- a/common/src/main/java/org/conscrypt/metrics/Protocol.java
+++ b/common/src/main/java/org/conscrypt/metrics/Protocol.java
@@ -33,7 +33,7 @@
TLS_PROTO_FAILED(0xFFFF),
;
- final byte id;
+ final int id;
public int getId() {
return this.id;
@@ -59,6 +59,6 @@
}
private Protocol(int id) {
- this.id = (byte) id;
+ this.id = id;
}
}
\ No newline at end of file
diff --git a/common/src/test/java/org/conscrypt/ConscryptJava7Suite.java b/common/src/test/java/org/conscrypt/ConscryptJava7Suite.java
deleted file mode 100644
index a400599..0000000
--- a/common/src/test/java/org/conscrypt/ConscryptJava7Suite.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2018 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 org.conscrypt;
-
-import static org.conscrypt.TestUtils.installConscryptAsDefaultProvider;
-
-import org.conscrypt.ct.CTVerifierTest;
-import org.conscrypt.ct.SerializationTest;
-import org.conscrypt.java.security.AlgorithmParameterGeneratorTestDH;
-import org.conscrypt.java.security.AlgorithmParameterGeneratorTestDSA;
-import org.conscrypt.java.security.AlgorithmParametersPSSTest;
-import org.conscrypt.java.security.AlgorithmParametersTestAES;
-import org.conscrypt.java.security.AlgorithmParametersTestDES;
-import org.conscrypt.java.security.AlgorithmParametersTestDESede;
-import org.conscrypt.java.security.AlgorithmParametersTestDH;
-import org.conscrypt.java.security.AlgorithmParametersTestDSA;
-import org.conscrypt.java.security.AlgorithmParametersTestEC;
-import org.conscrypt.java.security.AlgorithmParametersTestGCM;
-import org.conscrypt.java.security.AlgorithmParametersTestOAEP;
-import org.conscrypt.java.security.KeyFactoryTestDH;
-import org.conscrypt.java.security.KeyFactoryTestDSA;
-import org.conscrypt.java.security.KeyFactoryTestEC;
-import org.conscrypt.java.security.KeyFactoryTestRSA;
-import org.conscrypt.java.security.KeyPairGeneratorTest;
-import org.conscrypt.java.security.KeyPairGeneratorTestDH;
-import org.conscrypt.java.security.KeyPairGeneratorTestDSA;
-import org.conscrypt.java.security.KeyPairGeneratorTestRSA;
-import org.conscrypt.java.security.MessageDigestTest;
-import org.conscrypt.java.security.SignatureTest;
-import org.conscrypt.java.security.cert.CertificateFactoryTest;
-import org.conscrypt.java.security.cert.X509CRLTest;
-import org.conscrypt.java.security.cert.X509CertificateTest;
-import org.conscrypt.javax.crypto.AeadCipherTest;
-import org.conscrypt.javax.crypto.CipherBasicsTest;
-import org.conscrypt.javax.crypto.KeyGeneratorTest;
-import org.conscrypt.javax.net.ssl.HttpsURLConnectionTest;
-import org.conscrypt.javax.net.ssl.KeyManagerFactoryTest;
-import org.conscrypt.javax.net.ssl.KeyStoreBuilderParametersTest;
-import org.conscrypt.javax.net.ssl.SNIHostNameTest;
-import org.conscrypt.javax.net.ssl.SSLContextTest;
-import org.conscrypt.javax.net.ssl.SSLEngineTest;
-import org.conscrypt.javax.net.ssl.SSLEngineVersionCompatibilityTest;
-import org.conscrypt.javax.net.ssl.SSLParametersTest;
-import org.conscrypt.javax.net.ssl.SSLServerSocketFactoryTest;
-import org.conscrypt.javax.net.ssl.SSLServerSocketTest;
-import org.conscrypt.javax.net.ssl.SSLSessionContextTest;
-import org.conscrypt.javax.net.ssl.SSLSessionTest;
-import org.conscrypt.javax.net.ssl.SSLSocketFactoryTest;
-import org.conscrypt.javax.net.ssl.SSLSocketTest;
-import org.conscrypt.javax.net.ssl.SSLSocketVersionCompatibilityTest;
-import org.conscrypt.javax.net.ssl.TrustManagerFactoryTest;
-import org.conscrypt.javax.net.ssl.X509KeyManagerTest;
-import org.junit.BeforeClass;
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-
-@RunWith(Suite.class)
-@Suite.SuiteClasses({
- // org.conscrypt tests
- CertPinManagerTest.class,
- ChainStrengthAnalyzerTest.class,
- TrustManagerImplTest.class,
- // org.conscrypt.ct tests
- CTVerifierTest.class,
- SerializationTest.class,
- // java.security tests
- CertificateFactoryTest.class,
- X509CertificateTest.class,
- X509CRLTest.class,
- AlgorithmParameterGeneratorTestDH.class,
- AlgorithmParameterGeneratorTestDSA.class,
- AlgorithmParametersPSSTest.class,
- AlgorithmParametersTestAES.class,
- AlgorithmParametersTestDES.class,
- AlgorithmParametersTestDESede.class,
- AlgorithmParametersTestDH.class,
- AlgorithmParametersTestDSA.class,
- AlgorithmParametersTestEC.class,
- AlgorithmParametersTestGCM.class,
- AlgorithmParametersTestOAEP.class,
- KeyFactoryTestDH.class,
- KeyFactoryTestDSA.class,
- KeyFactoryTestEC.class,
- KeyFactoryTestRSA.class,
- KeyPairGeneratorTest.class,
- KeyPairGeneratorTestDH.class,
- KeyPairGeneratorTestDSA.class,
- KeyPairGeneratorTestRSA.class,
- MessageDigestTest.class,
- SignatureTest.class,
- // javax.crypto tests
- AeadCipherTest.class,
- CipherBasicsTest.class,
- // CipherTest.class, // Lots of weird, broken behaviors in Sun* providers on OpenJDK 7
- // ECDHKeyAgreementTest.class, // EC keys are broken on OpenJDK 7
- KeyGeneratorTest.class,
- // javax.net.ssl tests
- HttpsURLConnectionTest.class,
- KeyManagerFactoryTest.class,
- KeyStoreBuilderParametersTest.class,
- SNIHostNameTest.class,
- SSLContextTest.class,
- SSLEngineTest.class,
- SSLEngineVersionCompatibilityTest.class,
- SSLParametersTest.class,
- SSLServerSocketFactoryTest.class,
- SSLServerSocketTest.class,
- SSLSessionContextTest.class,
- SSLSessionTest.class,
- SSLSocketFactoryTest.class,
- SSLSocketTest.class,
- SSLSocketVersionCompatibilityTest.class,
- TrustManagerFactoryTest.class,
- X509KeyManagerTest.class,
-})
-public class ConscryptJava7Suite {
-
- @BeforeClass
- public static void setupStatic() {
- installConscryptAsDefaultProvider();
- }
-
-}
diff --git a/common/src/test/java/org/conscrypt/ConscryptSuite.java b/common/src/test/java/org/conscrypt/ConscryptSuite.java
deleted file mode 100644
index c0950f2..0000000
--- a/common/src/test/java/org/conscrypt/ConscryptSuite.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2017 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 org.conscrypt;
-
-import static org.conscrypt.TestUtils.installConscryptAsDefaultProvider;
-
-import org.conscrypt.ct.CTVerifierTest;
-import org.conscrypt.ct.SerializationTest;
-import org.conscrypt.java.security.AlgorithmParameterGeneratorTestDH;
-import org.conscrypt.java.security.AlgorithmParameterGeneratorTestDSA;
-import org.conscrypt.java.security.AlgorithmParametersPSSTest;
-import org.conscrypt.java.security.AlgorithmParametersTestAES;
-import org.conscrypt.java.security.AlgorithmParametersTestDES;
-import org.conscrypt.java.security.AlgorithmParametersTestDESede;
-import org.conscrypt.java.security.AlgorithmParametersTestDH;
-import org.conscrypt.java.security.AlgorithmParametersTestDSA;
-import org.conscrypt.java.security.AlgorithmParametersTestEC;
-import org.conscrypt.java.security.AlgorithmParametersTestGCM;
-import org.conscrypt.java.security.AlgorithmParametersTestOAEP;
-import org.conscrypt.java.security.KeyFactoryTestDH;
-import org.conscrypt.java.security.KeyFactoryTestDSA;
-import org.conscrypt.java.security.KeyFactoryTestEC;
-import org.conscrypt.java.security.KeyFactoryTestRSA;
-import org.conscrypt.java.security.KeyFactoryTestRSACrt;
-import org.conscrypt.java.security.KeyFactoryTestRSACustom;
-import org.conscrypt.java.security.KeyFactoryTestXDH;
-import org.conscrypt.java.security.KeyPairGeneratorTest;
-import org.conscrypt.java.security.KeyPairGeneratorTestDH;
-import org.conscrypt.java.security.KeyPairGeneratorTestDSA;
-import org.conscrypt.java.security.KeyPairGeneratorTestRSA;
-import org.conscrypt.java.security.KeyPairGeneratorTestXDH;
-import org.conscrypt.java.security.MessageDigestTest;
-import org.conscrypt.java.security.SignatureTest;
-import org.conscrypt.java.security.cert.CertificateFactoryTest;
-import org.conscrypt.java.security.cert.X509CRLTest;
-import org.conscrypt.java.security.cert.X509CertificateTest;
-import org.conscrypt.javax.crypto.AeadCipherTest;
-import org.conscrypt.javax.crypto.CipherBasicsTest;
-import org.conscrypt.javax.crypto.CipherTest;
-import org.conscrypt.javax.crypto.ECDHKeyAgreementTest;
-import org.conscrypt.javax.crypto.KeyGeneratorTest;
-import org.conscrypt.javax.crypto.XDHKeyAgreementTest;
-import org.conscrypt.javax.net.ssl.HttpsURLConnectionTest;
-import org.conscrypt.javax.net.ssl.KeyManagerFactoryTest;
-import org.conscrypt.javax.net.ssl.KeyStoreBuilderParametersTest;
-import org.conscrypt.javax.net.ssl.SNIHostNameTest;
-import org.conscrypt.javax.net.ssl.SSLContextTest;
-import org.conscrypt.javax.net.ssl.SSLEngineTest;
-import org.conscrypt.javax.net.ssl.SSLEngineVersionCompatibilityTest;
-import org.conscrypt.javax.net.ssl.SSLParametersTest;
-import org.conscrypt.javax.net.ssl.SSLServerSocketFactoryTest;
-import org.conscrypt.javax.net.ssl.SSLServerSocketTest;
-import org.conscrypt.javax.net.ssl.SSLSessionContextTest;
-import org.conscrypt.javax.net.ssl.SSLSessionTest;
-import org.conscrypt.javax.net.ssl.SSLSocketFactoryTest;
-import org.conscrypt.javax.net.ssl.SSLSocketTest;
-import org.conscrypt.javax.net.ssl.SSLSocketVersionCompatibilityTest;
-import org.conscrypt.javax.net.ssl.TrustManagerFactoryTest;
-import org.conscrypt.javax.net.ssl.X509KeyManagerTest;
-import org.conscrypt.metrics.CipherSuiteTest;
-import org.conscrypt.metrics.OptionalMethodTest;
-import org.conscrypt.metrics.ProtocolTest;
-import org.junit.BeforeClass;
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-
-@RunWith(Suite.class)
-@Suite.SuiteClasses({
- // org.conscrypt tests
- CertPinManagerTest.class,
- ChainStrengthAnalyzerTest.class,
- HostnameVerifierTest.class,
- HpkeContextRecipientTest.class,
- HpkeContextSenderTest.class,
- HpkeContextTest.class,
- HpkeSuiteTest.class,
- HpkeTestVectorsTest.class,
- NativeCryptoArgTest.class,
- TrustManagerImplTest.class,
- // org.conscrypt.ct tests
- CTVerifierTest.class,
- SerializationTest.class,
- // java.security tests
- CertificateFactoryTest.class,
- X509CertificateTest.class,
- X509CRLTest.class,
- AlgorithmParameterGeneratorTestDH.class,
- AlgorithmParameterGeneratorTestDSA.class,
- AlgorithmParametersPSSTest.class,
- AlgorithmParametersTestAES.class,
- AlgorithmParametersTestDES.class,
- AlgorithmParametersTestDESede.class,
- AlgorithmParametersTestDH.class,
- AlgorithmParametersTestDSA.class,
- AlgorithmParametersTestEC.class,
- AlgorithmParametersTestGCM.class,
- AlgorithmParametersTestOAEP.class,
- BufferUtilsTest.class,
- CipherSuiteTest.class,
- KeyFactoryTestDH.class,
- KeyFactoryTestDSA.class,
- KeyFactoryTestEC.class,
- KeyFactoryTestRSA.class,
- KeyFactoryTestRSACrt.class,
- KeyFactoryTestRSACustom.class,
- KeyFactoryTestXDH.class,
- KeyPairGeneratorTest.class,
- KeyPairGeneratorTestDH.class,
- KeyPairGeneratorTestDSA.class,
- KeyPairGeneratorTestRSA.class,
- KeyPairGeneratorTestXDH.class,
- MessageDigestTest.class,
- SignatureTest.class,
- // javax.crypto tests
- AeadCipherTest.class,
- CipherBasicsTest.class,
- CipherTest.class,
- MacTest.class,
- ECDHKeyAgreementTest.class,
- KeyGeneratorTest.class,
- XDHKeyAgreementTest.class,
- // javax.net.ssl tests
- HttpsURLConnectionTest.class,
- KeyManagerFactoryTest.class,
- KeyStoreBuilderParametersTest.class,
- OptionalMethodTest.class,
- ProtocolTest.class,
- SNIHostNameTest.class,
- SSLContextTest.class,
- SSLEngineTest.class,
- SSLEngineVersionCompatibilityTest.class,
- SSLParametersTest.class,
- SSLServerSocketFactoryTest.class,
- SSLServerSocketTest.class,
- SSLSessionContextTest.class,
- SSLSessionTest.class,
- SSLSocketFactoryTest.class,
- SSLSocketTest.class,
- SSLSocketVersionCompatibilityTest.class,
- TrustManagerFactoryTest.class,
- VeryBasicHttpServerTest.class,
- X509KeyManagerTest.class,
-})
-public class ConscryptSuite {
-
- @BeforeClass
- public static void setupStatic() {
- installConscryptAsDefaultProvider();
- }
-
-}
diff --git a/common/src/test/java/org/conscrypt/MacTest.java b/common/src/test/java/org/conscrypt/MacTest.java
index 1fadbd6..b258563 100644
--- a/common/src/test/java/org/conscrypt/MacTest.java
+++ b/common/src/test/java/org/conscrypt/MacTest.java
@@ -127,6 +127,11 @@
macBytes = generateReusingMac(algorithm, keyBytes, msgBytes);
assertArrayEquals(failMessage("Re-use Mac", baseFailMsg, macBytes),
expectedBytes, macBytes);
+
+ // Calculated using a pre-loved Mac with the same key
+ macBytes = generateReusingMacSameKey(algorithm, secretKey, msgBytes);
+ assertArrayEquals(failMessage("Re-use Mac same key", baseFailMsg, macBytes),
+ expectedBytes, macBytes);
}
}
@@ -382,6 +387,19 @@
return mac.doFinal();
}
+ private byte[] generateReusingMacSameKey(String algorithm, SecretKeySpec key, byte[] message)
+ throws Exception {
+ Mac mac = getConscryptMac(algorithm, key);
+
+ // Calculate a MAC over some other message.
+ byte[] otherMessage = new byte[message.length];
+ mac.doFinal(otherMessage);
+
+ // The MAC should now have been reset to compute a new MAC with the same
+ // key.
+ return mac.doFinal(message);
+ }
+
private Mac getConscryptMac(String algorithm) throws Exception {
return getConscryptMac(algorithm, null);
}
diff --git a/common/src/test/java/org/conscrypt/ct/CTVerifierTest.java b/common/src/test/java/org/conscrypt/ct/CTVerifierTest.java
index 9aaf8db..85e5458 100644
--- a/common/src/test/java/org/conscrypt/ct/CTVerifierTest.java
+++ b/common/src/test/java/org/conscrypt/ct/CTVerifierTest.java
@@ -45,7 +45,7 @@
PublicKey key = TestUtils.readPublicKeyPemFile("ct-server-key-public.pem");
- final CTLogInfo log = new CTLogInfo(key, "Test Log", "foo");
+ final CTLogInfo log = new CTLogInfo(key, CTLogInfo.STATE_USABLE, "Test Log", "foo");
CTLogStore store = new CTLogStore() {
@Override
public CTLogInfo getKnownLog(byte[] logId) {
diff --git a/common/src/test/java/org/conscrypt/javax/crypto/ScryptTest.java b/common/src/test/java/org/conscrypt/javax/crypto/ScryptTest.java
new file mode 100644
index 0000000..133306c
--- /dev/null
+++ b/common/src/test/java/org/conscrypt/javax/crypto/ScryptTest.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2022 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 org.conscrypt.javax.crypto;
+
+import static org.conscrypt.TestUtils.decodeHex;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.security.spec.KeySpec;
+import java.util.List;
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.SecretKeySpec;
+import org.conscrypt.ScryptKeySpec;
+import org.conscrypt.TestUtils;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public final class ScryptTest {
+ @Parameters(name = "{0}")
+ public static String[] params() {
+ return new String[] {
+ "SCRYPT",
+ "1.3.6.1.4.1.11591.4.11",
+ "OID.1.3.6.1.4.1.11591.4.11"
+ };
+ }
+
+ @Parameter
+ public String alias;
+
+ // One of the test vectors from RFC 7914
+ private static final char[] TEST_PASSWORD = "password".toCharArray();
+ private static final byte[] TEST_SALT = "NaCl".getBytes(StandardCharsets.UTF_8);
+ private static final int TEST_COST = 1024;
+ private static final int TEST_BLOCKSIZE = 8;
+ private static final int TEST_PARALLELIZATION = 16;
+ private static final int TEST_KEY_SIZE = 512;
+ private static final byte[] TEST_KEY = decodeHex(
+ "fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b373162"
+ + "2eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640");
+
+
+ private final List<String[]> testVectors = readTestVectors();
+
+ // Column indices in test vector CSV file
+ private static final int PASSWORD_INDEX = 0;
+ private static final int SALT_INDEX = 1;
+ private static final int N_INDEX = 2;
+ private static final int R_INDEX = 3;
+ private static final int P_INDEX = 4;
+ private static final int KEY_INDEX = 5;
+
+ @BeforeClass
+ public static void setUp() {
+ TestUtils.assumeAllowsUnsignedCrypto();
+ }
+
+ @Test
+ public void smokeTest() throws Exception {
+ SecretKeyFactory factory = SecretKeyFactory.getInstance(alias);
+ assertEquals(alias, factory.getAlgorithm());
+
+ ScryptKeySpec spec = new ScryptKeySpec(TEST_PASSWORD, TEST_SALT,
+ TEST_COST, TEST_BLOCKSIZE, TEST_PARALLELIZATION, TEST_KEY_SIZE);
+ SecretKey key = factory.generateSecret(spec);
+ assertArrayEquals(TEST_KEY, key.getEncoded());
+
+ // Convert for use with AES
+ SecretKeySpec aesKey = makeAesKeySpec(key);
+
+ // Make sure we can actually use the result
+ checkKeyIsUsableWithAes(aesKey);
+ }
+
+ @Test
+ public void duckTypingTest() throws Exception {
+ SecretKeyFactory factory = SecretKeyFactory.getInstance(alias);
+
+ KeySpec spec = new MyPrivateKeySpec(TEST_PASSWORD, TEST_SALT,
+ TEST_COST, TEST_BLOCKSIZE, TEST_PARALLELIZATION, TEST_KEY_SIZE);
+
+ SecretKey key = factory.generateSecret(spec);
+ assertArrayEquals(TEST_KEY, key.getEncoded());
+ }
+
+ private SecretKeySpec makeAesKeySpec(SecretKey key) {
+ assertEquals("RAW", key.getFormat());
+ byte[] bytes = key.getEncoded();
+ // Truncate to first 32 bytes if necessary
+ int len = Math.min(32, bytes.length);
+ return new SecretKeySpec(bytes, 0, len, "AES");
+ }
+
+ private void checkKeyIsUsableWithAes(SecretKeySpec spec) throws Exception {
+ // Terrible encryption mode but saves messing with IVs which don't matter here.
+ Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
+
+ cipher.init(Cipher.ENCRYPT_MODE, spec);
+ byte[] input = "The quick brown fox jumps over the lazy dog".getBytes(StandardCharsets.UTF_8);
+ byte[] encrypted = cipher.doFinal(input);
+ assertNotEquals(encrypted[0], input[0]);
+
+ cipher.init(Cipher.DECRYPT_MODE, spec);
+ byte[] decrypted = cipher.doFinal(encrypted);
+ assertArrayEquals(input, decrypted);
+ }
+
+ @Test
+ public void knownAnswerTest() throws Exception {
+ for (String[] entry : testVectors) {
+ char[] password = entry[PASSWORD_INDEX].toCharArray();
+ byte[] salt = entry[SALT_INDEX].getBytes(StandardCharsets.UTF_8);
+ int n = Integer.parseInt(entry[N_INDEX]);
+ int r = Integer.parseInt(entry[R_INDEX]);
+ int p = Integer.parseInt(entry[P_INDEX]);
+ byte[] expectedBytes = decodeHex(entry[KEY_INDEX]);
+
+ ScryptKeySpec spec = new ScryptKeySpec(password, salt, n, r, p, expectedBytes.length * 8);
+ SecretKeyFactory factory = SecretKeyFactory.getInstance(alias);
+ SecretKey key = factory.generateSecret(spec);
+ assertNotNull(key);
+ assertArrayEquals(expectedBytes, key.getEncoded());
+ }
+ }
+
+ private List<String[]> readTestVectors() {
+ try {
+ return TestUtils.readCsvResource("crypto/scrypt.csv");
+
+ } catch (IOException e) {
+ throw new AssertionError("Unable to load Scrypt test vectors", e);
+ }
+ }
+
+ public static class MyPrivateKeySpec implements KeySpec {
+ private final char[] password;
+ private final byte[] salt;
+ private final int n;
+ private final int r;
+ private final int p;
+ private final int keyOutputBits;
+
+ public MyPrivateKeySpec(char[] password, byte[] salt, int n, int r, int p, int keyOutputBits) {
+ this.password = password;
+ this.salt = salt;
+ this.n = n;
+ this.r = r;
+ this.p = p;
+ this.keyOutputBits = keyOutputBits;
+ }
+
+ public char[] getPassword() {
+ return password;
+ }
+
+ public byte[] getSalt() {
+ return salt;
+ }
+
+ public int getCostParameter() {
+ return n;
+ }
+
+ public int getBlockSize() {
+ return r;
+ }
+
+ public int getParallelizationParameter() {
+ return p;
+ }
+
+ public int getKeyLength() {
+ return keyOutputBits;
+ }
+ }
+}
diff --git a/common/src/test/java/org/conscrypt/javax/net/ssl/SSLContextTest.java b/common/src/test/java/org/conscrypt/javax/net/ssl/SSLContextTest.java
index 40acd1b..f24d864 100644
--- a/common/src/test/java/org/conscrypt/javax/net/ssl/SSLContextTest.java
+++ b/common/src/test/java/org/conscrypt/javax/net/ssl/SSLContextTest.java
@@ -119,6 +119,16 @@
}
@Test
+ public void test_SSLContext_allProtocols() throws Exception {
+ SSLConfigurationAsserts.assertSSLContextDefaultConfiguration(SSLContext.getDefault());
+
+ for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS_ALL) {
+ SSLContext sslContext = SSLContext.getInstance(protocol);
+ sslContext.init(null, null, null);
+ }
+ }
+
+ @Test
public void test_SSLContext_pskOnlyConfiguration_defaultProviderOnly() throws Exception {
// Test the scenario where only a PSKKeyManager is provided and no TrustManagers are
// provided.
diff --git a/common/src/test/java/org/conscrypt/javax/net/ssl/SSLSocketVersionCompatibilityTest.java b/common/src/test/java/org/conscrypt/javax/net/ssl/SSLSocketVersionCompatibilityTest.java
index 707cbab..e2cc79b 100644
--- a/common/src/test/java/org/conscrypt/javax/net/ssl/SSLSocketVersionCompatibilityTest.java
+++ b/common/src/test/java/org/conscrypt/javax/net/ssl/SSLSocketVersionCompatibilityTest.java
@@ -16,10 +16,16 @@
package org.conscrypt.javax.net.ssl;
+import libcore.junit.util.SwitchTargetSdkVersionRule;
+import libcore.junit.util.SwitchTargetSdkVersionRule.TargetSdkVersion;
+
import static org.conscrypt.TestUtils.osName;
import static org.conscrypt.TestUtils.isOsx;
import static org.conscrypt.TestUtils.isLinux;
import static org.conscrypt.TestUtils.isWindows;
+import static org.conscrypt.TestUtils.isTlsV1Deprecated;
+import static org.conscrypt.TestUtils.isTlsV1Filtered;
+import static org.conscrypt.TestUtils.isTlsV1Supported;
import static org.conscrypt.TestUtils.UTF_8;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
@@ -109,7 +115,9 @@
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import tests.net.DelegatingSSLSocketFactory;
@@ -123,6 +131,9 @@
@RunWith(Parameterized.class)
public class SSLSocketVersionCompatibilityTest {
+ @Rule
+ public TestRule switchTargetSdkVersionRule = SwitchTargetSdkVersionRule.getInstance();
+
@Parameterized.Parameters(name = "{index}: {0} client, {1} server")
public static Iterable<Object[]> data() {
return Arrays.asList(new Object[][] {
@@ -1692,7 +1703,7 @@
@Test
public void test_SSLSocket_ClientHello_ALPN() throws Exception {
final String[] protocolList = new String[] { "h2", "http/1.1" };
-
+
ForEachRunner.runNamed(new ForEachRunner.Callback<SSLSocketFactory>() {
@Override
public void run(SSLSocketFactory sslSocketFactory) throws Exception {
@@ -1928,7 +1939,35 @@
}
@Test
- public void test_SSLSocket_SSLv3Unsupported() throws Exception {
+ public void test_SSLSocket_TLSv1Supported() throws Exception {
+ assumeTrue(isTlsV1Supported());
+ TestSSLContext context = new TestSSLContext.Builder()
+ .clientProtocol(clientVersion)
+ .serverProtocol(serverVersion)
+ .build();
+ final SSLSocket client =
+ (SSLSocket) context.clientContext.getSocketFactory().createSocket();
+ client.setEnabledProtocols(new String[] {"TLSv1", "TLSv1.1"});
+ assertEquals(2, client.getEnabledProtocols().length);
+ }
+
+ @TargetSdkVersion(35)
+ @Test
+ public void test_SSLSocket_SSLv3Unsupported_35() throws Exception {
+ assumeFalse(isTlsV1Filtered());
+ TestSSLContext context = new TestSSLContext.Builder()
+ .clientProtocol(clientVersion)
+ .serverProtocol(serverVersion)
+ .build();
+ final SSLSocket client =
+ (SSLSocket) context.clientContext.getSocketFactory().createSocket();
+ assertThrows(IllegalArgumentException.class, () -> client.setEnabledProtocols(new String[] {"SSLv3"}));
+ assertThrows(IllegalArgumentException.class, () -> client.setEnabledProtocols(new String[] {"SSL"}));
+ }
+
+ @TargetSdkVersion(34)
+ @Test
+ public void test_SSLSocket_SSLv3Unsupported_34() throws Exception {
TestSSLContext context = new TestSSLContext.Builder()
.clientProtocol(clientVersion)
.serverProtocol(serverVersion)
@@ -1946,6 +1985,40 @@
}
}
+ @TargetSdkVersion(34)
+ @Test
+ public void test_TLSv1Filtered_34() throws Exception {
+ TestSSLContext context = new TestSSLContext.Builder()
+ .clientProtocol(clientVersion)
+ .serverProtocol(serverVersion)
+ .build();
+ final SSLSocket client =
+ (SSLSocket) context.clientContext.getSocketFactory().createSocket();
+ client.setEnabledProtocols(new String[] {"TLSv1", "TLSv1.1", "TLSv1.2"});
+ assertEquals(1, client.getEnabledProtocols().length);
+ assertEquals("TLSv1.2", client.getEnabledProtocols()[0]);
+ }
+
+ @TargetSdkVersion(35)
+ @Test
+ public void test_TLSv1Filtered_35() throws Exception {
+ assumeFalse(isTlsV1Filtered());
+ TestSSLContext context = new TestSSLContext.Builder()
+ .clientProtocol(clientVersion)
+ .serverProtocol(serverVersion)
+ .build();
+ final SSLSocket client =
+ (SSLSocket) context.clientContext.getSocketFactory().createSocket();
+ assertThrows(IllegalArgumentException.class, () ->
+ client.setEnabledProtocols(new String[] {"TLSv1", "TLSv1.1", "TLSv1.2"}));
+ }
+
+ @Test
+ public void test_TLSv1Unsupported_notEnabled() throws Exception {
+ assumeTrue(!isTlsV1Supported());
+ assertTrue(isTlsV1Deprecated());
+ }
+
// Under some circumstances, the file descriptor socket may get finalized but still
// be reused by the JDK's built-in HTTP connection reuse code. Ensure that a
// SocketException is thrown if that happens.
diff --git a/common/src/test/resources/crypto/scrypt.csv b/common/src/test/resources/crypto/scrypt.csv
new file mode 100644
index 0000000..88bdfb8
--- /dev/null
+++ b/common/src/test/resources/crypto/scrypt.csv
@@ -0,0 +1,8 @@
+# Scrypt test vectors from RFC 7914
+# Data is in the format:
+# password,salt,n,r,p,key
+,,16,1,1,77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3fede21442fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628cf35e20c38d18906
+password,NaCl,1024,8,16,fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640
+pleaseletmein,SodiumChloride,16384,8,1,7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887
+# Following vector exceeds memory limits with defaults
+# pleaseletmein,SodiumChloride,1048576,8,1,2101cb9b6a511aaeaddbbe09cf70f881ec568d574a2ffd4dabe5ee9820adaa478e56fd8f4ba5d09ffa1c6d927c40f4c337304049e8a952fbcbf45c6fa77a41a4
diff --git a/conscrypt.aconfig b/conscrypt.aconfig
new file mode 100644
index 0000000..781a626
--- /dev/null
+++ b/conscrypt.aconfig
@@ -0,0 +1,26 @@
+# Copyright (C) 2024 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: "com.android.org.conscrypt"
+container: "com.android.conscrypt"
+
+flag {
+ namespace: "core_libraries"
+ name: "certificate_transparency_platform"
+ description: "This flag controls whether conscrypt will interpret the NetworkSecurityConfig for Certificate Transparency"
+ bug: "319829948"
+ # APIs provided by a mainline module can only use a frozen flag.
+ is_fixed_read_only: true
+}
+
diff --git a/libcore-stub/src/main/java/libcore/net/NetworkSecurityPolicy.java b/libcore-stub/src/main/java/libcore/net/NetworkSecurityPolicy.java
index d9c87a4..e7ca0f1 100644
--- a/libcore-stub/src/main/java/libcore/net/NetworkSecurityPolicy.java
+++ b/libcore-stub/src/main/java/libcore/net/NetworkSecurityPolicy.java
@@ -27,7 +27,6 @@
* permitted. See {@link #isCleartextTrafficPermitted()}.
*/
public abstract class NetworkSecurityPolicy {
-
private static volatile NetworkSecurityPolicy instance = new DefaultNetworkSecurityPolicy();
public static NetworkSecurityPolicy getInstance() {
diff --git a/lint-baseline.xml b/lint-baseline.xml
deleted file mode 100644
index 70db717..0000000
--- a/lint-baseline.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
-
- <issue
- id="NewApi"
- message="Call requires API level R (current min is 29): `android.system.ErrnoException#rethrowAsSocketException`"
- errorLine1=" throw errnoException.rethrowAsSocketException();"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="external/conscrypt/repackaged/platform/src/main/java/com/android/org/conscrypt/Platform.java"
- line="134"
- column="34"/>
- </issue>
-
-</issues>
diff --git a/openjdk/build.gradle b/openjdk/build.gradle
index 2c0adb1..af31b63 100644
--- a/openjdk/build.gradle
+++ b/openjdk/build.gradle
@@ -315,28 +315,12 @@
publishing.publications.maven.artifact jarTask.get()
}
-
-// TODO(prb) Still provide a mechanism for testing on Java 7?
-// Check which version
-//def javaError = new ByteArrayOutputStream()
-//exec {
-// executable test.executable
-// System.out.println("Running tests with java executable: " + test.executable + ".")
-// args = ['-version']
-// ignoreExitValue true
-// errorOutput = javaError
-//}
-//
-//def suiteClass = (javaError.toString() =~ /"1[.]7[.].*"/) ?
-// "org/conscrypt/ConscryptJava7Suite.class" : "org/conscrypt/ConscryptSuite.class";
-def suiteClass = "org/conscrypt/ConscryptSuite.class";
-
test {
- include suiteClass, "org/conscrypt/ConscryptOpenJdkSuite.class"
+ include "org/conscrypt/ConscryptOpenJdkSuite.class"
}
def testFdSocket = tasks.register("testFdSocket", Test) {
- include suiteClass, "org/conscrypt/ConscryptOpenJdkSuite.class"
+ include "org/conscrypt/ConscryptOpenJdkSuite.class"
InvokerHelper.setProperties(testLogging, test.testLogging.properties)
systemProperties = test.systemProperties
systemProperty "org.conscrypt.useEngineSocketByDefault", false
diff --git a/openjdk/src/main/java/org/conscrypt/Platform.java b/openjdk/src/main/java/org/conscrypt/Platform.java
index 2a07ac4..306574c 100644
--- a/openjdk/src/main/java/org/conscrypt/Platform.java
+++ b/openjdk/src/main/java/org/conscrypt/Platform.java
@@ -344,20 +344,6 @@
}
/**
- * Wraps an old AndroidOpenSSL key instance. This is not needed on RI.
- */
- @SuppressWarnings("unused")
- static OpenSSLKey wrapRsaKey(@SuppressWarnings("unused") PrivateKey javaKey) {
- return null;
- }
-
- /**
- * Logs to the system EventLog system.
- */
- @SuppressWarnings("unused")
- static void logEvent(@SuppressWarnings("unused") String message) {}
-
- /**
* For unbundled versions, SNI is always enabled by default.
*/
@SuppressWarnings("unused")
@@ -816,4 +802,12 @@
public static boolean isTlsV1Deprecated() {
return true;
}
+
+ public static boolean isTlsV1Filtered() {
+ return false;
+ }
+
+ public static boolean isTlsV1Supported() {
+ return false;
+ }
}
diff --git a/openjdk/src/test/java/org/conscrypt/ConscryptOpenJdkSuite.java b/openjdk/src/test/java/org/conscrypt/ConscryptOpenJdkSuite.java
index ef8bb1e..d5401e3 100644
--- a/openjdk/src/test/java/org/conscrypt/ConscryptOpenJdkSuite.java
+++ b/openjdk/src/test/java/org/conscrypt/ConscryptOpenJdkSuite.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2023 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 org.conscrypt;
import static org.conscrypt.TestUtils.installConscryptAsDefaultProvider;
@@ -160,10 +176,8 @@
X509KeyManagerTest.class,
})
public class ConscryptOpenJdkSuite {
-
- @BeforeClass
- public static void setupStatic() {
- installConscryptAsDefaultProvider();
- }
-
+ @BeforeClass
+ public static void setupStatic() {
+ installConscryptAsDefaultProvider();
+ }
}
diff --git a/openjdk/src/test/resources/test_blocklist_ca2.pem b/openjdk/src/test/resources/test_blocklist_ca2.pem
new file mode 100644
index 0000000..ca33594
--- /dev/null
+++ b/openjdk/src/test/resources/test_blocklist_ca2.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDHTCCAgWgAwIBAgIUY4GMRArmOpdsPFvMChsC64re26kwDQYJKoZIhvcNAQEL
+BQAwHjEcMBoGA1UEAwwTYmxhY2tsaXN0IHRlc3QgQ0EgMjAeFw0yNDA2MDcwNTAx
+NTJaFw0zNDA2MDUwNTAxNTJaMB4xHDAaBgNVBAMME2JsYWNrbGlzdCB0ZXN0IENB
+IDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCZiCGg9O8L4drk5R0J
+AwFvnm4aS2NZXnD0xUwE4iK0Nhw0Fb5A/yd4aW1RL8gCqcYXQywHrQAZq+PBUnG9
+ArtRoOTugkSD7gRFPFi7xcq6tdjVinkG33BUqSoyZb584sAwLfuKmG4WgGF6Bm2g
+vTh4kzvvqzJmWiDMHAxJCUiE+OQ3kBKoGUqplyn97Td3ZKs6mi1lAYV5xAu5M3EK
+fFC6g4Ckvy/5ZMLrROwz2bTtMQEsIRAeFRWWQJlDKF4RbceFmhDavwMSHCZu9ZGM
+HPAapXg+3LdQM+uqiQoguItY9dv1SJbWlcsxl5NzqDkPLfZeIhMTEYk/PtMKIsLk
+7aUvAgMBAAGjUzBRMB0GA1UdDgQWBBQyrTPvjxNE7FvnFRmD50u9H+o5nTAfBgNV
+HSMEGDAWgBQyrTPvjxNE7FvnFRmD50u9H+o5nTAPBgNVHRMBAf8EBTADAQH/MA0G
+CSqGSIb3DQEBCwUAA4IBAQBOAdrI1ycTfwL/PMUCXAlwbosKFyDESgGgbfE0blHc
+MkT0AY4ODxU2+oEM+UTwFJ/3ZC88hlJdhqL4spwC1lTCP8DpydxzR+KN8iEUDQT6
+MeXjmll7qUzk5f+/xF3BCp+5ZqympYNPT3vwf25k308aT6/LNrWCvQYxPJJue1aS
+kPQU6y3ktgsdXmSL696fGi/VcuNmJKjDJn+po7NS+F07Addnf5t1v9iwNMI2OwiG
+LzZ/3wiQNU03KlM6fiy++e0VIxrxShg1cYMlKQanzFo3cFkigT5JNDHTA2gVV0Kz
+7bEMyIVMLL59ky3bVdxVCJdi5brhgqV1C8Wly0bgm555
+-----END CERTIFICATE-----
diff --git a/openjdk/src/test/resources/test_blocklist_ca2_key.pem b/openjdk/src/test/resources/test_blocklist_ca2_key.pem
new file mode 100644
index 0000000..f8a4bb5
--- /dev/null
+++ b/openjdk/src/test/resources/test_blocklist_ca2_key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCZiCGg9O8L4drk
+5R0JAwFvnm4aS2NZXnD0xUwE4iK0Nhw0Fb5A/yd4aW1RL8gCqcYXQywHrQAZq+PB
+UnG9ArtRoOTugkSD7gRFPFi7xcq6tdjVinkG33BUqSoyZb584sAwLfuKmG4WgGF6
+Bm2gvTh4kzvvqzJmWiDMHAxJCUiE+OQ3kBKoGUqplyn97Td3ZKs6mi1lAYV5xAu5
+M3EKfFC6g4Ckvy/5ZMLrROwz2bTtMQEsIRAeFRWWQJlDKF4RbceFmhDavwMSHCZu
+9ZGMHPAapXg+3LdQM+uqiQoguItY9dv1SJbWlcsxl5NzqDkPLfZeIhMTEYk/PtMK
+IsLk7aUvAgMBAAECggEAP2Jww8MrJ4QseyBNvukzQBIv0YI7N2uihaMokcGMY0sN
+lME/RRUyBee8nm50DAlsQzFTra2SI4cP5cG0PDyy+e3LZd55C+CJec4Csi7j1fZ6
+WRqsgZZgiUs3pQvVOzjf8GQje6IXnQmOdLLPsrM766eZcIaErbXa4XlY5xRCkMaO
+RavPwvbAFKKKCjndJs5OZpwZwR/UcHMlYLR3Dg+ozzlG48dMr0ao/3bimGPsc8/t
+eXzlVq2vi8xdRm53MdzarH9VWTYg3AalKEedLxxfvyGaZrpviCZdftHvH+sRruCy
+D280CSlmwLFc5xVGQTN9zNolEWarxU4fcusgmyfXrQKBgQDVqbrSOBDKF1WlyT/J
+vsCCRywoTBVDxvB0BeoC3ICHh5KISbtfjqy/CR4qLGnuov0ZXVR5UmGHs3gl21qm
+HjX1IRWo+8bfaoxBqK1zcFd4XtkPNPtEAcQvH0MFjnBXd0WcC/7qzvUUIC2RGuWY
+YmxCj4uFdSTLwLwiTDwXdAy7HQKBgQC39C8Ygu7MlTO9EpyQdoOSbQC+VgaPPABO
+LgQLoGH5K7sNOjutHo3Bt3iKFsdPkTHkZc3alBhH+61zgbsmGFrNJI+XRgkeGpLR
+/6Bbi7ivswsJcHmodOKOr62RKMJArwqOqN2MhNlZTBDjgIy4owN2B0YHwd9GTQWu
+JOjfwHwjuwKBgQCpxjtPjQMyQcZpfHc2LF81Za5dus7u0yX/Wy+t5F4w0vYJW2UK
+sgjrpygT5MSrvVEVlYZo/J/Ivz+J/TmTY9AGHqriYmWM41HdXlWss6idWehp3/SD
+/k9QDiwoPx1fMsPaEeIV3Cr7OfJbKZ8kLZjObtczTXjWeihDrIXXMPxotQKBgQC3
+mO1QZ43zfo7PDL5aqQ6UnFp7ndyaJOahIOhEumROjsj4YMCi/rW5PGcAW8+9qErF
+jJ4ypFC/t3/cowSo9vHZgb4W233KH/edxKbF9+Py6J4BY9LowRBGHSz8jlOiv5Gn
+5P6KeyV7LKJGjkzlEz4nFQdeQq+XuNQMhSYv/CtqdQKBgEQKDQRiKgl4DjbDWNjV
+3EUFH/LBvwPUXnrfeECXuyiTrTHrUsTtahcrjTQs/ByX15YSmyVhbUSsYQ6dkafZ
+aVNl9zNLQYYa2y3VbBs0q5xEW+iCmc4w/LsW+mnUiFmKlYVokwGVEDkqMyDkk3oB
+58f2hIryzy4MDkh0Iqixr6o1
+-----END PRIVATE KEY-----
diff --git a/platform/src/main/java/org/conscrypt/CertBlocklistImpl.java b/platform/src/main/java/org/conscrypt/CertBlocklistImpl.java
index 2428d4c..305b74b 100644
--- a/platform/src/main/java/org/conscrypt/CertBlocklistImpl.java
+++ b/platform/src/main/java/org/conscrypt/CertBlocklistImpl.java
@@ -24,14 +24,16 @@
import java.io.IOException;
import java.io.RandomAccessFile;
import java.math.BigInteger;
-import java.security.GeneralSecurityException;
import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -41,14 +43,35 @@
private static final Logger logger = Logger.getLogger(CertBlocklistImpl.class.getName());
private final Set<BigInteger> serialBlocklist;
- private final Set<ByteString> pubkeyBlocklist;
+ private final Set<ByteArray> sha1PubkeyBlocklist;
+ private final Set<ByteArray> sha256PubkeyBlocklist;
+ private Map<ByteArray, Boolean> cache;
+
+ /**
+ * Number of entries in the cache. The cache contains public keys which are
+ * at most 4096 bits (512 bytes) for RSA. For a cache size of 64, that is
+ * at most 512 * 64 = 32,768 bytes.
+ */
+ private static final int CACHE_SIZE = 64;
/**
* public for testing only.
*/
- public CertBlocklistImpl(Set<BigInteger> serialBlocklist, Set<ByteString> pubkeyBlocklist) {
+ public CertBlocklistImpl(Set<BigInteger> serialBlocklist, Set<ByteArray> sha1PubkeyBlocklist) {
+ this(serialBlocklist, sha1PubkeyBlocklist, Collections.emptySet());
+ }
+
+ public CertBlocklistImpl(Set<BigInteger> serialBlocklist, Set<ByteArray> sha1PubkeyBlocklist,
+ Set<ByteArray> sha256PubkeyBlocklist) {
+ this.cache = Collections.synchronizedMap(new LinkedHashMap<ByteArray, Boolean>() {
+ @Override
+ protected boolean removeEldestEntry(Map.Entry<ByteArray, Boolean> eldest) {
+ return size() > CACHE_SIZE;
+ }
+ });
this.serialBlocklist = serialBlocklist;
- this.pubkeyBlocklist = pubkeyBlocklist;
+ this.sha1PubkeyBlocklist = sha1PubkeyBlocklist;
+ this.sha256PubkeyBlocklist = sha256PubkeyBlocklist;
}
public static CertBlocklist getDefault() {
@@ -56,10 +79,14 @@
String blocklistRoot = androidData + "/misc/keychain/";
String defaultPubkeyBlocklistPath = blocklistRoot + "pubkey_blacklist.txt";
String defaultSerialBlocklistPath = blocklistRoot + "serial_blacklist.txt";
+ String defaultPubkeySha256BlocklistPath = blocklistRoot + "pubkey_sha256_blocklist.txt";
- Set<ByteString> pubkeyBlocklist = readPublicKeyBlockList(defaultPubkeyBlocklistPath);
+ Set<ByteArray> sha1PubkeyBlocklist =
+ readPublicKeyBlockList(defaultPubkeyBlocklistPath, "SHA-1");
+ Set<ByteArray> sha256PubkeyBlocklist =
+ readPublicKeyBlockList(defaultPubkeySha256BlocklistPath, "SHA-256");
Set<BigInteger> serialBlocklist = readSerialBlockList(defaultSerialBlocklistPath);
- return new CertBlocklistImpl(serialBlocklist, pubkeyBlocklist);
+ return new CertBlocklistImpl(serialBlocklist, sha1PubkeyBlocklist, sha256PubkeyBlocklist);
}
private static boolean isHex(String value) {
@@ -72,8 +99,8 @@
}
}
- private static boolean isPubkeyHash(String value) {
- if (value.length() != 40) {
+ private static boolean isPubkeyHash(String value, int expectedHashLength) {
+ if (value.length() != expectedHashLength) {
logger.log(Level.WARNING, "Invalid pubkey hash length: " + value.length());
return false;
}
@@ -129,32 +156,12 @@
}
private static Set<BigInteger> readSerialBlockList(String path) {
-
- /* Start out with a base set of known bad values.
- *
- * WARNING: Do not add short serials to this list!
- *
- * Since this currently doesn't compare the serial + issuer, you
- * should only add serials that have enough entropy here. Short
- * serials may inadvertently match a certificate that was issued
- * not in compliance with the Baseline Requirements.
+ /*
+ * Deprecated. Serials may inadvertently match a certificate that was
+ * issued not in compliance with the Baseline Requirements. Prefer
+ * using the certificate public key.
*/
- Set<BigInteger> bl = new HashSet<BigInteger>(Arrays.asList(
- // From http://src.chromium.org/viewvc/chrome/trunk/src/net/base/x509_certificate.cc?revision=78748&view=markup
- // Not a real certificate. For testing only.
- new BigInteger("077a59bcd53459601ca6907267a6dd1c", 16),
- new BigInteger("047ecbe9fca55f7bd09eae36e10cae1e", 16),
- new BigInteger("d8f35f4eb7872b2dab0692e315382fb0", 16),
- new BigInteger("b0b7133ed096f9b56fae91c874bd3ac0", 16),
- new BigInteger("9239d5348f40d1695a745470e1f23f43", 16),
- new BigInteger("e9028b9578e415dc1a710a2b88154447", 16),
- new BigInteger("d7558fdaf5f1105bb213282b707729a3", 16),
- new BigInteger("f5c86af36162f13a64f54f6dc9587c06", 16),
- new BigInteger("392a434f0e07df1f8aa305de34e0c229", 16),
- new BigInteger("3e75ced46b693021218830ae86a82a71", 16)
- ));
-
- // attempt to augment it with values taken from gservices
+ Set<BigInteger> bl = new HashSet<BigInteger>();
String serialBlocklist = readBlocklist(path);
if (!serialBlocklist.equals("")) {
for (String value : serialBlocklist.split(",", -1)) {
@@ -170,15 +177,13 @@
return Collections.unmodifiableSet(bl);
}
- private static Set<ByteString> readPublicKeyBlockList(String path) {
-
- // start out with a base set of known bad values
- Set<ByteString> bl = new HashSet<ByteString>(toByteStrings(
+ static final byte[][] SHA1_BUILTINS = {
// Blocklist test cert for CTS. The cert and key can be found in
// src/test/resources/blocklist_test_ca.pem and
// src/test/resources/blocklist_test_ca_key.pem.
"bae78e6bed65a2bf60ddedde7fd91e825865e93d".getBytes(UTF_8),
- // From http://src.chromium.org/viewvc/chrome/branches/782/src/net/base/x509_certificate.cc?r1=98750&r2=98749&pathrev=98750
+ // From
+ // http://src.chromium.org/viewvc/chrome/branches/782/src/net/base/x509_certificate.cc?r1=98750&r2=98749&pathrev=98750
// C=NL, O=DigiNotar, CN=DigiNotar Root CA/emailAddress=info@diginotar.nl
"410f36363258f30b347d12ce4863e433437806a8".getBytes(UTF_8),
// Subject: CN=DigiNotar Cyber CA
@@ -205,16 +210,49 @@
"783333c9687df63377efceddd82efa9101913e8e".getBytes(UTF_8),
// Subject: Subject: C=FR, O=DG Tr\xC3\xA9sor, CN=AC DG Tr\xC3\xA9sor SSL
// Issuer: C=FR, O=DGTPE, CN=AC DGTPE Signature Authentification
- "3ecf4bbbe46096d514bb539bb913d77aa4ef31bf".getBytes(UTF_8)
- ));
+ "3ecf4bbbe46096d514bb539bb913d77aa4ef31bf".getBytes(UTF_8),
+ };
+
+ static final byte[][] SHA256_BUILTINS = {
+ // Blocklist test cert for CTS. The cert and key can be found in
+ // src/test/resources/blocklist_test_ca2.pem and
+ // src/test/resources/blocklist_test_ca2_key.pem.
+ "809964b15e9bd312993d9984045551f503f2cf8e68f39188921ba30fe623f9fd".getBytes(UTF_8),
+ };
+
+ private static Set<ByteArray> readPublicKeyBlockList(String path, String hashType) {
+ Set<ByteArray> bl;
+
+ switch (hashType) {
+ case "SHA-1":
+ bl = new HashSet<ByteArray>(toByteArrays(SHA1_BUILTINS));
+ break;
+ case "SHA-256":
+ bl = new HashSet<ByteArray>(toByteArrays(SHA256_BUILTINS));
+ break;
+ default:
+ throw new RuntimeException(
+ "Unknown hashType: " + hashType + ". Expected SHA-1 or SHA-256");
+ }
+
+ MessageDigest md;
+ try {
+ md = MessageDigest.getInstance(hashType);
+ } catch (NoSuchAlgorithmException e) {
+ logger.log(Level.SEVERE, "Unable to get " + hashType + " MessageDigest", e);
+ return bl;
+ }
+ // The hashes are encoded with hexadecimal values. There should be
+ // twice as many characters as the digest length in bytes.
+ int hashLength = md.getDigestLength() * 2;
// attempt to augment it with values taken from gservices
String pubkeyBlocklist = readBlocklist(path);
if (!pubkeyBlocklist.equals("")) {
for (String value : pubkeyBlocklist.split(",", -1)) {
value = value.trim();
- if (isPubkeyHash(value)) {
- bl.add(new ByteString(value.getBytes(UTF_8)));
+ if (isPubkeyHash(value, hashLength)) {
+ bl.add(new ByteArray(value.getBytes(UTF_8)));
} else {
logger.log(Level.WARNING, "Tried to blocklist invalid pubkey " + value);
}
@@ -224,22 +262,46 @@
return bl;
}
- @Override
- public boolean isPublicKeyBlockListed(PublicKey publicKey) {
- byte[] encoded = publicKey.getEncoded();
+ private static boolean isPublicKeyBlockListed(
+ byte[] encodedPublicKey, Set<ByteArray> blocklist, String hashType) {
MessageDigest md;
try {
- md = MessageDigest.getInstance("SHA1");
- } catch (GeneralSecurityException e) {
- logger.log(Level.SEVERE, "Unable to get SHA1 MessageDigest", e);
+ md = MessageDigest.getInstance(hashType);
+ } catch (NoSuchAlgorithmException e) {
+ logger.log(Level.SEVERE, "Unable to get " + hashType + " MessageDigest", e);
return false;
}
- byte[] out = toHex(md.digest(encoded));
- for (ByteString blocklisted : pubkeyBlocklist) {
- if (Arrays.equals(blocklisted.bytes, out)) {
+ ByteArray out = new ByteArray(toHex(md.digest(encodedPublicKey)));
+ if (blocklist.contains(out)) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isPublicKeyBlockListed(PublicKey publicKey) {
+ byte[] encodedPublicKey = publicKey.getEncoded();
+ // cacheKey is a view on encodedPublicKey. Because it is used as a key
+ // for a Map, its underlying array (encodedPublicKey) should not be
+ // modified.
+ ByteArray cacheKey = new ByteArray(encodedPublicKey);
+ Boolean cachedResult = cache.get(cacheKey);
+ if (cachedResult != null) {
+ return cachedResult.booleanValue();
+ }
+ if (!sha1PubkeyBlocklist.isEmpty()) {
+ if (isPublicKeyBlockListed(encodedPublicKey, sha1PubkeyBlocklist, "SHA-1")) {
+ cache.put(cacheKey, true);
return true;
}
}
+ if (!sha256PubkeyBlocklist.isEmpty()) {
+ if (isPublicKeyBlockListed(encodedPublicKey, sha256PubkeyBlocklist, "SHA-256")) {
+ cache.put(cacheKey, true);
+ return true;
+ }
+ }
+ cache.put(cacheKey, false);
return false;
}
@@ -263,37 +325,11 @@
return serialBlocklist.contains(serial);
}
- private static List<ByteString> toByteStrings(byte[]... allBytes) {
- List<ByteString> byteStrings = new ArrayList<>(allBytes.length + 1);
+ private static List<ByteArray> toByteArrays(byte[]... allBytes) {
+ List<ByteArray> byteArrays = new ArrayList<>(allBytes.length + 1);
for (byte[] bytes : allBytes) {
- byteStrings.add(new ByteString(bytes));
+ byteArrays.add(new ByteArray(bytes));
}
- return byteStrings;
- }
-
- private static class ByteString {
- final byte[] bytes;
-
- public ByteString(byte[] bytes) {
- this.bytes = bytes;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
- if (!(o instanceof ByteString)) {
- return false;
- }
-
- ByteString other = (ByteString) o;
- return Arrays.equals(bytes, other.bytes);
- }
-
- @Override
- public int hashCode() {
- return Arrays.hashCode(bytes);
- }
+ return byteArrays;
}
}
diff --git a/platform/src/main/java/org/conscrypt/InternalUtil.java b/platform/src/main/java/org/conscrypt/InternalUtil.java
deleted file mode 100644
index 39558c4..0000000
--- a/platform/src/main/java/org/conscrypt/InternalUtil.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2017 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 org.conscrypt;
-
-import java.io.InputStream;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PublicKey;
-import org.conscrypt.OpenSSLX509CertificateFactory.ParsingException;
-
-/**
- * Helper to initialize the JNI libraries. This version runs when compiled
- * as part of the platform.
- */
-@Internal
-public final class InternalUtil {
- public static PublicKey logKeyToPublicKey(byte[] logKey)
- throws NoSuchAlgorithmException {
- try {
- return new OpenSSLKey(NativeCrypto.EVP_parse_public_key(logKey)).getPublicKey();
- } catch (ParsingException e) {
- throw new NoSuchAlgorithmException(e);
- }
- }
-
- public static PublicKey readPublicKeyPem(InputStream pem) throws InvalidKeyException, NoSuchAlgorithmException {
- return OpenSSLKey.fromPublicKeyPemInputStream(pem).getPublicKey();
- }
-
- private InternalUtil() {
- }
-}
diff --git a/platform/src/main/java/org/conscrypt/Platform.java b/platform/src/main/java/org/conscrypt/Platform.java
index ef69618..8344ed9 100644
--- a/platform/src/main/java/org/conscrypt/Platform.java
+++ b/platform/src/main/java/org/conscrypt/Platform.java
@@ -25,6 +25,7 @@
import android.system.StructTimeval;
import dalvik.system.BlockGuard;
import dalvik.system.CloseGuard;
+import dalvik.system.VMRuntime;
import java.io.FileDescriptor;
import java.io.IOException;
import java.lang.System;
@@ -68,6 +69,7 @@
import org.conscrypt.ct.CTPolicyImpl;
import org.conscrypt.metrics.CipherSuite;
import org.conscrypt.metrics.ConscryptStatsLog;
+import org.conscrypt.metrics.OptionalMethod;
import org.conscrypt.metrics.Protocol;
import sun.security.x509.AlgorithmId;
@@ -264,35 +266,6 @@
}
}
- /**
- * Wraps an old AndroidOpenSSL key instance. This is not needed on platform
- * builds since we didn't backport, so return null.
- */
- static OpenSSLKey wrapRsaKey(PrivateKey key) {
- return null;
- }
-
- /**
- * Logs to the system EventLog system.
- */
- static void logEvent(String message) {
- try {
- Class processClass = Class.forName("android.os.Process");
- Object processInstance = processClass.newInstance();
- Method myUidMethod = processClass.getMethod("myUid", (Class[]) null);
- int uid = (Integer) myUidMethod.invoke(processInstance);
-
- Class eventLogClass = Class.forName("android.util.EventLog");
- Object eventLogInstance = eventLogClass.newInstance();
- Method writeEventMethod = eventLogClass.getMethod(
- "writeEvent", new Class[] {Integer.TYPE, Object[].class});
- writeEventMethod.invoke(eventLogInstance, 0x534e4554 /* SNET */,
- new Object[] {"conscrypt", uid, message});
- } catch (Exception e) {
- // Do not log and fail silently
- }
- }
-
static SSLEngine wrapEngine(ConscryptEngine engine) {
return new Java8EngineWrapper(engine);
}
@@ -491,6 +464,10 @@
}
static boolean isCTVerificationRequired(String hostname) {
+ if (Flags.certificateTransparencyPlatform()) {
+ return NetworkSecurityPolicy.getInstance()
+ .isCertificateTransparencyVerificationRequired(hostname);
+ }
return false;
}
@@ -570,4 +547,32 @@
public static boolean isTlsV1Deprecated() {
return true;
}
+
+ public static boolean isTlsV1Filtered() {
+ Object targetSdkVersion = getTargetSdkVersion();
+ if ((targetSdkVersion != null) && ((int) targetSdkVersion > 34))
+ return false;
+ return true;
+ }
+
+ public static boolean isTlsV1Supported() {
+ return false;
+ }
+
+ static Object getTargetSdkVersion() {
+ try {
+ Class<?> vmRuntime = Class.forName("dalvik.system.VMRuntime");
+ if (vmRuntime == null) {
+ return null;
+ }
+ OptionalMethod getSdkVersion =
+ new OptionalMethod(vmRuntime,
+ "getTargetSdkVersion");
+ return getSdkVersion.invokeStatic();
+ } catch (ClassNotFoundException e) {
+ return null;
+ } catch (NullPointerException e) {
+ return null;
+ }
+ }
}
diff --git a/platform/src/main/java/org/conscrypt/TrustedCertificateStore.java b/platform/src/main/java/org/conscrypt/TrustedCertificateStore.java
index 14df376..bcf7816 100644
--- a/platform/src/main/java/org/conscrypt/TrustedCertificateStore.java
+++ b/platform/src/main/java/org/conscrypt/TrustedCertificateStore.java
@@ -35,6 +35,7 @@
import java.util.List;
import java.util.Set;
import javax.security.auth.x500.X500Principal;
+import org.conscrypt.ArrayUtils;
import org.conscrypt.io.IoUtils;
import org.conscrypt.metrics.OptionalMethod;
@@ -116,7 +117,7 @@
if ((System.getProperty("system.certs.enabled") != null)
&& (System.getProperty("system.certs.enabled")).equals("true"))
return false;
- if (updatableDir.exists() && !(updatableDir.list().length == 0))
+ if (updatableDir.exists() && !(ArrayUtils.isEmpty(updatableDir.list())))
return true;
return false;
}
diff --git a/platform/src/main/java/org/conscrypt/ct/CTLogStoreImpl.java b/platform/src/main/java/org/conscrypt/ct/CTLogStoreImpl.java
index 0f37a8d..2a70ba7 100644
--- a/platform/src/main/java/org/conscrypt/ct/CTLogStoreImpl.java
+++ b/platform/src/main/java/org/conscrypt/ct/CTLogStoreImpl.java
@@ -16,243 +16,165 @@
package org.conscrypt.ct;
+import static java.nio.charset.StandardCharsets.US_ASCII;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
-import java.util.Arrays;
+import java.util.Base64;
import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Scanner;
-import java.util.Set;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.conscrypt.ByteArray;
import org.conscrypt.Internal;
-import org.conscrypt.InternalUtil;
+import org.conscrypt.OpenSSLKey;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
@Internal
public class CTLogStoreImpl implements CTLogStore {
- private static final Charset US_ASCII = StandardCharsets.US_ASCII;
+ private static final Logger logger = Logger.getLogger(CTLogStoreImpl.class.getName());
+ public static final String V3_PATH = "/misc/keychain/ct/v3/log_list.json";
+ private static final Path defaultLogList;
- /**
- * Thrown when parsing of a log file fails.
- */
- public static class InvalidLogFileException extends Exception {
- public InvalidLogFileException() {
- }
-
- public InvalidLogFileException(String message) {
- super(message);
- }
-
- public InvalidLogFileException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public InvalidLogFileException(Throwable cause) {
- super(cause);
- }
- }
-
- private static final File defaultUserLogDir;
- private static final File defaultSystemLogDir;
- // Lazy loaded by CTLogStoreImpl()
- private static volatile CTLogInfo[] defaultFallbackLogs = null;
static {
String ANDROID_DATA = System.getenv("ANDROID_DATA");
- String ANDROID_ROOT = System.getenv("ANDROID_ROOT");
- defaultUserLogDir = new File(ANDROID_DATA + "/misc/keychain/trusted_ct_logs/current/");
- defaultSystemLogDir = new File(ANDROID_ROOT + "/etc/security/ct_known_logs/");
+ defaultLogList = Paths.get(ANDROID_DATA, V3_PATH);
}
- private final File userLogDir;
- private final File systemLogDir;
- private final CTLogInfo[] fallbackLogs;
+ private enum State {
+ UNINITIALIZED,
+ LOADED,
+ NOT_FOUND,
+ MALFORMED,
+ }
- private final HashMap<ByteBuffer, CTLogInfo> logCache = new HashMap<>();
- private final Set<ByteBuffer> missingLogCache
- = Collections.synchronizedSet(new HashSet<ByteBuffer>());
+ private final Path logList;
+ private State state;
+ private String version;
+ private Map<ByteArray, CTLogInfo> logs;
public CTLogStoreImpl() {
- this(defaultUserLogDir,
- defaultSystemLogDir,
- getDefaultFallbackLogs());
+ this(defaultLogList);
}
- public CTLogStoreImpl(File userLogDir, File systemLogDir, CTLogInfo[] fallbackLogs) {
- this.userLogDir = userLogDir;
- this.systemLogDir = systemLogDir;
- this.fallbackLogs = fallbackLogs;
+ public CTLogStoreImpl(Path logList) {
+ this.state = State.UNINITIALIZED;
+ this.logList = logList;
}
@Override
public CTLogInfo getKnownLog(byte[] logId) {
- ByteBuffer buf = ByteBuffer.wrap(logId);
- CTLogInfo log = logCache.get(buf);
+ if (logId == null) {
+ return null;
+ }
+ if (!ensureLogListIsLoaded()) {
+ return null;
+ }
+ ByteArray buf = new ByteArray(logId);
+ CTLogInfo log = logs.get(buf);
if (log != null) {
return log;
}
- if (missingLogCache.contains(buf)) {
- return null;
- }
-
- log = findKnownLog(logId);
- if (log != null) {
- logCache.put(buf, log);
- } else {
- missingLogCache.add(buf);
- }
-
- return log;
- }
-
- private CTLogInfo findKnownLog(byte[] logId) {
- String filename = hexEncode(logId);
- try {
- return loadLog(new File(userLogDir, filename));
- } catch (InvalidLogFileException e) {
- return null;
- } catch (FileNotFoundException e) {
- // Ignored
- }
-
- try {
- return loadLog(new File(systemLogDir, filename));
- } catch (InvalidLogFileException e) {
- return null;
- } catch (FileNotFoundException e) {
- // Ignored
- }
-
- // If the updateable logs dont exist then use the fallback logs.
- if (!userLogDir.exists()) {
- for (CTLogInfo log: fallbackLogs) {
- if (Arrays.equals(logId, log.getID())) {
- return log;
- }
- }
- }
return null;
}
- public static CTLogInfo[] getDefaultFallbackLogs() {
- CTLogInfo[] result = defaultFallbackLogs;
- if (result == null) {
- // single-check idiom
- defaultFallbackLogs = result = createDefaultFallbackLogs();
- }
- return result;
- }
-
- private static CTLogInfo[] createDefaultFallbackLogs() {
- CTLogInfo[] logs = new CTLogInfo[KnownLogs.LOG_COUNT];
- for (int i = 0; i < KnownLogs.LOG_COUNT; i++) {
- try {
- PublicKey key = InternalUtil.logKeyToPublicKey(KnownLogs.LOG_KEYS[i]);
-
- logs[i] = new CTLogInfo(key,
- KnownLogs.LOG_DESCRIPTIONS[i],
- KnownLogs.LOG_URLS[i]);
- } catch (NoSuchAlgorithmException e) {
- throw new RuntimeException(e);
+ /* Ensures the log list is loaded.
+ * Returns true if the log list is usable.
+ */
+ private boolean ensureLogListIsLoaded() {
+ synchronized (this) {
+ if (state == State.UNINITIALIZED) {
+ state = loadLogList();
}
+ return state == State.LOADED;
}
-
- defaultFallbackLogs = logs;
- return logs;
}
- /**
- * Load a CTLogInfo from a file.
- * @throws FileNotFoundException if the file does not exist
- * @throws InvalidLogFileException if the file could not be parsed properly
- * @return a CTLogInfo or null if the file is empty
- */
- public static CTLogInfo loadLog(File file) throws FileNotFoundException,
- InvalidLogFileException {
- return loadLog(new FileInputStream(file));
- }
-
- /**
- * Load a CTLogInfo from a textual representation. Closes {@code input} upon completion
- * of loading.
- *
- * @throws InvalidLogFileException if the input could not be parsed properly
- * @return a CTLogInfo or null if the input is empty
- */
- public static CTLogInfo loadLog(InputStream input) throws InvalidLogFileException {
- final Scanner scan = new Scanner(input, "UTF-8");
- scan.useDelimiter("\n");
-
- String description = null;
- String url = null;
- String key = null;
+ private State loadLogList() {
+ byte[] content;
try {
- // If the scanner can't even read one token then the file must be empty/blank
- if (!scan.hasNext()) {
- return null;
- }
-
- while (scan.hasNext()) {
- String[] parts = scan.next().split(":", 2);
- if (parts.length < 2) {
- continue;
- }
-
- String name = parts[0];
- String value = parts[1];
- switch (name) {
- case "description":
- description = value;
- break;
- case "url":
- url = value;
- break;
- case "key":
- key = value;
- break;
+ content = Files.readAllBytes(logList);
+ } catch (IOException e) {
+ return State.NOT_FOUND;
+ }
+ if (content == null) {
+ return State.NOT_FOUND;
+ }
+ JSONObject json;
+ try {
+ json = new JSONObject(new String(content, UTF_8));
+ } catch (JSONException e) {
+ logger.log(Level.WARNING, "Unable to parse log list", e);
+ return State.MALFORMED;
+ }
+ HashMap<ByteArray, CTLogInfo> logsMap = new HashMap<>();
+ try {
+ version = json.getString("version");
+ JSONArray operators = json.getJSONArray("operators");
+ for (int i = 0; i < operators.length(); i++) {
+ JSONObject operator = operators.getJSONObject(i);
+ String operatorName = operator.getString("name");
+ JSONArray logs = operator.getJSONArray("logs");
+ for (int j = 0; j < logs.length(); j++) {
+ JSONObject log = logs.getJSONObject(j);
+ String description = log.getString("description");
+ byte[] logId = Base64.getDecoder().decode(log.getString("log_id"));
+ PublicKey key = parsePubKey(log.getString("key"));
+ JSONObject stateObject = log.getJSONObject("state");
+ int logState = parseState(stateObject.keys().next());
+ String url = log.getString("url");
+ CTLogInfo logInfo = new CTLogInfo(key, logState, description, url);
+ logsMap.put(new ByteArray(logId), logInfo);
}
}
- } finally {
- scan.close();
+ } catch (JSONException | IllegalArgumentException e) {
+ logger.log(Level.WARNING, "Unable to parse log list", e);
+ return State.MALFORMED;
}
+ this.logs = Collections.unmodifiableMap(logsMap);
+ return State.LOADED;
+ }
- if (description == null || url == null || key == null) {
- throw new InvalidLogFileException("Missing one of 'description', 'url' or 'key'");
+ private static int parseState(String state) {
+ switch (state) {
+ case "pending":
+ return CTLogInfo.STATE_PENDING;
+ case "qualified":
+ return CTLogInfo.STATE_QUALIFIED;
+ case "usable":
+ return CTLogInfo.STATE_USABLE;
+ case "readonly":
+ return CTLogInfo.STATE_READONLY;
+ case "retired":
+ return CTLogInfo.STATE_RETIRED;
+ case "rejected":
+ return CTLogInfo.STATE_REJECTED;
+ default:
+ throw new IllegalArgumentException("Unknown log state: " + state);
}
+ }
+ private static PublicKey parsePubKey(String key) {
+ byte[] pem = ("-----BEGIN PUBLIC KEY-----\n" + key + "\n-----END PUBLIC KEY-----")
+ .getBytes(US_ASCII);
PublicKey pubkey;
try {
- pubkey = InternalUtil.readPublicKeyPem(new ByteArrayInputStream(
- ("-----BEGIN PUBLIC KEY-----\n" +
- key + "\n" +
- "-----END PUBLIC KEY-----").getBytes(US_ASCII)));
- } catch (InvalidKeyException e) {
- throw new InvalidLogFileException(e);
- } catch (NoSuchAlgorithmException e) {
- throw new InvalidLogFileException(e);
+ pubkey = OpenSSLKey.fromPublicKeyPemInputStream(new ByteArrayInputStream(pem))
+ .getPublicKey();
+ } catch (InvalidKeyException | NoSuchAlgorithmException e) {
+ throw new IllegalArgumentException(e);
}
-
- return new CTLogInfo(pubkey, description, url);
- }
-
- private final static char[] HEX_DIGITS = new char[] {
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
- };
-
- private static String hexEncode(byte[] data) {
- StringBuilder sb = new StringBuilder(data.length * 2);
- for (byte b: data) {
- sb.append(HEX_DIGITS[(b >> 4) & 0x0f]);
- sb.append(HEX_DIGITS[b & 0x0f]);
- }
- return sb.toString();
+ return pubkey;
}
}
diff --git a/platform/src/main/java/org/conscrypt/ct/KnownLogs.java b/platform/src/main/java/org/conscrypt/ct/KnownLogs.java
deleted file mode 100644
index dba00cb..0000000
--- a/platform/src/main/java/org/conscrypt/ct/KnownLogs.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-/* This file is generated by print_log_list.py
- * https://github.com/google/certificate-transparency/blob/master/python/utilities/log_list/print_log_list.py */
-
-package org.conscrypt.ct;
-
-import org.conscrypt.Internal;
-
-@Internal
-public final class KnownLogs {
- public static final int LOG_COUNT = 8;
- public static final String[] LOG_DESCRIPTIONS = new String[] {
- "Google 'Pilot' log",
- "Google 'Aviator' log",
- "DigiCert Log Server",
- "Google 'Rocketeer' log",
- "Certly.IO log",
- "Izenpe log",
- "Symantec log",
- "Venafi log",
- };
- public static final String[] LOG_URLS = new String[] {
- "ct.googleapis.com/pilot",
- "ct.googleapis.com/aviator",
- "ct1.digicert-ct.com/log",
- "ct.googleapis.com/rocketeer",
- "log.certly.io",
- "ct.izenpe.com",
- "ct.ws.symantec.com",
- "ctlog.api.venafi.com",
- };
- public static final byte[][] LOG_KEYS = new byte[][] {
- // Google 'Pilot' log
- new byte[] {
- 48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72,
- -50, 61, 3, 1, 7, 3, 66, 0, 4, 125, -88, 75, 18, 41, -128, -93, 61, -83,
- -45, 90, 119, -72, -52, -30, -120, -77, -91, -3, -15, -45, 12, -51, 24,
- 12, -24, 65, 70, -24, -127, 1, 27, 21, -31, 75, -15, 27, 98, -35, 54, 10,
- 8, 24, -70, -19, 11, 53, -124, -48, -98, 64, 60, 45, -98, -101, -126,
- 101, -67, 31, 4, 16, 65, 76, -96
- },
- // Google 'Aviator' log
- new byte[] {
- 48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72,
- -50, 61, 3, 1, 7, 3, 66, 0, 4, -41, -12, -52, 105, -78, -28, 14, -112,
- -93, -118, -22, 90, 112, 9, 79, -17, 19, 98, -48, -115, 73, 96, -1, 27,
- 64, 80, 7, 12, 109, 113, -122, -38, 37, 73, -115, 101, -31, 8, 13, 71,
- 52, 107, -67, 39, -68, -106, 33, 62, 52, -11, -121, 118, 49, -79, 127,
- 29, -55, -123, 59, 13, -9, 31, 63, -23
- },
- // DigiCert Log Server
- new byte[] {
- 48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72,
- -50, 61, 3, 1, 7, 3, 66, 0, 4, 2, 70, -59, -66, 27, -69, -126, 64, 22,
- -24, -63, -46, -84, 25, 105, 19, 89, -8, -8, 112, -123, 70, 64, -71, 56,
- -80, 35, -126, -88, 100, 76, 127, -65, -69, 52, -97, 74, 95, 40, -118,
- -49, 25, -60, 0, -10, 54, 6, -109, 101, -19, 76, -11, -87, 33, 98, 90,
- -40, -111, -21, 56, 36, 64, -84, -24
- },
- // Google 'Rocketeer' log
- new byte[] {
- 48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72,
- -50, 61, 3, 1, 7, 3, 66, 0, 4, 32, 91, 24, -56, 60, -63, -117, -77, 49,
- 8, 0, -65, -96, -112, 87, 43, -73, 71, -116, 111, -75, 104, -80, -114,
- -112, 120, -23, -96, 115, -22, 79, 40, 33, 46, -100, -64, -12, 22, 27,
- -86, -7, -43, -41, -87, -128, -61, 78, 47, 82, 60, -104, 1, 37, 70, 36,
- 37, 40, 35, 119, 45, 5, -62, 64, 122
- },
- // Certly.IO log
- new byte[] {
- 48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72,
- -50, 61, 3, 1, 7, 3, 66, 0, 4, 11, 35, -53, -123, 98, -104, 97, 72, 4,
- 115, -21, 84, 93, -13, -48, 7, -116, 45, 25, 45, -116, 54, -11, -21,
- -113, 1, 66, 10, 124, -104, 38, 39, -63, -75, -35, -110, -109, -80, -82,
- -8, -101, 61, 12, -40, 76, 78, 29, -7, 21, -5, 71, 104, 123, -70, 102,
- -73, 37, -100, -48, 74, -62, 102, -37, 72
- },
- // Izenpe log
- new byte[] {
- 48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72,
- -50, 61, 3, 1, 7, 3, 66, 0, 4, 39, 100, 57, 12, 45, -36, 80, 24, -8, 33,
- 0, -94, 14, -19, 44, -22, 62, 117, -70, -97, -109, 100, 9, 0, 17, -60,
- 17, 23, -85, 92, -49, 15, 116, -84, -75, -105, -112, -109, 0, 91, -72,
- -21, -9, 39, 61, -39, -78, 10, -127, 95, 47, 13, 117, 56, -108, 55, -103,
- 30, -10, 7, 118, -32, -18, -66
- },
- // Symantec log
- new byte[] {
- 48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72,
- -50, 61, 3, 1, 7, 3, 66, 0, 4, -106, -22, -84, 28, 70, 12, 27, 85, -36,
- 13, -4, -75, -108, 39, 70, 87, 66, 112, 58, 105, 24, -30, -65, 59, -60,
- -37, -85, -96, -12, -74, 108, -64, 83, 63, 77, 66, 16, 51, -16, 88, -105,
- -113, 107, -66, 114, -12, 42, -20, 28, 66, -86, 3, 47, 26, 126, 40, 53,
- 118, -103, 8, 61, 33, 20, -122
- },
- // Venafi log
- new byte[] {
- 48, -126, 1, 34, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 1, 5, 0,
- 3, -126, 1, 15, 0, 48, -126, 1, 10, 2, -126, 1, 1, 0, -94, 90, 72, 31,
- 23, 82, -107, 53, -53, -93, 91, 58, 31, 83, -126, 118, -108, -93, -1,
- -128, -14, 28, 55, 60, -64, -79, -67, -63, 89, -117, -85, 45, 101, -109,
- -41, -13, -32, 4, -43, -102, 111, -65, -42, 35, 118, 54, 79, 35, -103,
- -53, 84, 40, -83, -116, 21, 75, 101, 89, 118, 65, 74, -100, -90, -9, -77,
- 59, 126, -79, -91, 73, -92, 23, 81, 108, -128, -36, 42, -112, 80, 75,
- -120, 36, -23, -91, 18, 50, -109, 4, 72, -112, 2, -6, 95, 14, 48, -121,
- -114, 85, 118, 5, -18, 42, 76, -50, -93, 106, 105, 9, 110, 37, -83, -126,
- 118, 15, -124, -110, -6, 56, -42, -122, 78, 36, -113, -101, -80, 114,
- -53, -98, -30, 107, 63, -31, 109, -55, 37, 117, 35, -120, -95, 24, 88, 6,
- 35, 51, 120, -38, 0, -48, 56, -111, 103, -46, -90, 125, 39, -105, 103,
- 90, -63, -13, 47, 23, -26, -22, -46, 91, -24, -127, -51, -3, -110, 104,
- -25, -13, 6, -16, -23, 114, -124, -18, 1, -91, -79, -40, 51, -38, -50,
- -125, -91, -37, -57, -49, -42, 22, 126, -112, 117, 24, -65, 22, -36, 50,
- 59, 109, -115, -85, -126, 23, 31, -119, 32, -115, 29, -102, -26, 77, 35,
- 8, -33, 120, 111, -58, 5, -65, 95, -82, -108, -105, -37, 95, 100, -44,
- -18, 22, -117, -93, -124, 108, 113, 43, -15, -85, 127, 93, 13, 50, -18,
- 4, -30, -112, -20, 65, -97, -5, 57, -63, 2, 3, 1, 0, 1
- },
- };
-}
diff --git a/platform/src/test/java/org/conscrypt/CertBlocklistTest.java b/platform/src/test/java/org/conscrypt/CertBlocklistTest.java
index 39561e5..4d9a5c1 100644
--- a/platform/src/test/java/org/conscrypt/CertBlocklistTest.java
+++ b/platform/src/test/java/org/conscrypt/CertBlocklistTest.java
@@ -29,6 +29,7 @@
public class CertBlocklistTest extends TestCase {
private static final String BLOCKLIST_CA = "test_blocklist_ca.pem";
+ private static final String BLOCKLIST_CA2 = "test_blocklist_ca2.pem";
private static final String BLOCKLISTED_CHAIN = "blocklist_test_chain.pem";
private static final String BLOCKLIST_FALLBACK_VALID_CA = "blocklist_test_valid_ca.pem";
private static final String BLOCKLISTED_VALID_CHAIN = "blocklist_test_valid_chain.pem";
@@ -43,6 +44,15 @@
}
/**
+ * Ensure that the test blocklisted CA 2 is actually blocklisted by default.
+ */
+ public void testBlocklistedPublicKeySHA256() throws Exception {
+ X509Certificate blocklistedCa = loadCertificate(BLOCKLIST_CA2);
+ CertBlocklist blocklist = CertBlocklistImpl.getDefault();
+ assertTrue(blocklist.isPublicKeyBlockListed(blocklistedCa.getPublicKey()));
+ }
+
+ /**
* Check that the blocklisted CA is rejected even if it used as a root of trust
*/
public void testBlocklistedCaUntrusted() throws Exception {
diff --git a/platform/src/test/java/org/conscrypt/ct/CTLogStoreImplTest.java b/platform/src/test/java/org/conscrypt/ct/CTLogStoreImplTest.java
index f95a3e6..33a5fa7 100644
--- a/platform/src/test/java/org/conscrypt/ct/CTLogStoreImplTest.java
+++ b/platform/src/test/java/org/conscrypt/ct/CTLogStoreImplTest.java
@@ -16,189 +16,120 @@
package org.conscrypt.ct;
+import static java.nio.charset.StandardCharsets.US_ASCII;
import static java.nio.charset.StandardCharsets.UTF_8;
-import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
+import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
-import java.nio.charset.StandardCharsets;
import java.security.PublicKey;
+import java.util.Base64;
import junit.framework.TestCase;
-import org.conscrypt.InternalUtil;
+import org.conscrypt.OpenSSLKey;
public class CTLogStoreImplTest extends TestCase {
- private static final String[] LOG_KEYS = new String[] {
- "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmXg8sUUzwBYaWrRb+V0IopzQ6o3U" +
- "yEJ04r5ZrRXGdpYM8K+hB0pXrGRLI0eeWz+3skXrS0IO83AhA3GpRL6s6w==",
+ public void test_loadLogList() throws Exception {
+ // clang-format off
+ String content = "" +
+"{" +
+" \"version\": \"1.1\"," +
+" \"log_list_timestamp\": \"2024-01-01T11:55:12Z\"," +
+" \"operators\": [" +
+" {" +
+" \"name\": \"Operator 1\"," +
+" \"email\": [\"ct@operator1.com\"]," +
+" \"logs\": [" +
+" {" +
+" \"description\": \"Operator 1 'Test2024' log\"," +
+" \"log_id\": \"7s3QZNXbGs7FXLedtM0TojKHRny87N7DUUhZRnEftZs=\"," +
+" \"key\": \"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHblsqctplMVc5ramA7vSuNxUQxcomQwGAVAdnWTAWUYr3MgDHQW0LagJ95lB7QT75Ve6JgT2EVLOFGU7L3YrwA==\"," +
+" \"url\": \"https://operator1.example.com/logs/test2024/\"," +
+" \"mmd\": 86400," +
+" \"state\": {" +
+" \"usable\": {" +
+" \"timestamp\": \"2022-11-01T18:54:00Z\"" +
+" }" +
+" }," +
+" \"temporal_interval\": {" +
+" \"start_inclusive\": \"2024-01-01T00:00:00Z\"," +
+" \"end_exclusive\": \"2025-01-01T00:00:00Z\"" +
+" }" +
+" }," +
+" {" +
+" \"description\": \"Operator 1 'Test2025' log\"," +
+" \"log_id\": \"TnWjJ1yaEMM4W2zU3z9S6x3w4I4bjWnAsfpksWKaOd8=\"," +
+" \"key\": \"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIIKh+WdoqOTblJji4WiH5AltIDUzODyvFKrXCBjw/Rab0/98J4LUh7dOJEY7+66+yCNSICuqRAX+VPnV8R1Fmg==\"," +
+" \"url\": \"https://operator1.example.com/logs/test2025/\"," +
+" \"mmd\": 86400," +
+" \"state\": {" +
+" \"usable\": {" +
+" \"timestamp\": \"2023-11-26T12:00:00Z\"" +
+" }" +
+" }," +
+" \"temporal_interval\": {" +
+" \"start_inclusive\": \"2025-01-01T00:00:00Z\"," +
+" \"end_exclusive\": \"2025-07-01T00:00:00Z\"" +
+" }" +
+" }" +
+" ]" +
+" }," +
+" {" +
+" \"name\": \"Operator 2\"," +
+" \"email\": [\"ct@operator2.com\"]," +
+" \"logs\": [" +
+" {" +
+" \"description\": \"Operator 2 'Test2024' Log\"," +
+" \"log_id\": \"2ra/az+1tiKfm8K7XGvocJFxbLtRhIU0vaQ9MEjX+6s=\"," +
+" \"key\": \"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEd7Gbe4/mizX+OpIpLayKjVGKJfyTttegiyk3cR0zyswz6ii5H+Ksw6ld3Ze+9p6UJd02gdHrXSnDK0TxW8oVSA==\"," +
+" \"url\": \"https://operator2.example.com/logs/test2024/\"," +
+" \"mmd\": 86400," +
+" \"state\": {" +
+" \"usable\": {" +
+" \"timestamp\": \"2022-11-30T17:00:00Z\"" +
+" }" +
+" }," +
+" \"temporal_interval\": {" +
+" \"start_inclusive\": \"2024-01-01T00:00:00Z\"," +
+" \"end_exclusive\": \"2025-01-01T00:00:00Z\"" +
+" }" +
+" }" +
+" ]" +
+" }" +
+" ]" +
+"}";
+ // clang-format on
- "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAErEULmlBnX9L/+AK20hLYzPMFozYx" +
- "pP0Wm1ylqGkPEwuDKn9DSpNSOym49SN77BLGuAXu9twOW/qT+ddIYVBEIw==",
+ File logList = writeFile(content);
+ CTLogStore store = new CTLogStoreImpl(logList.toPath());
- "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEP6PGcXmjlyCBz2ZFUuUjrgbZLaEF" +
- "gfLUkt2cEqlSbb4vTuB6WWmgC9h0L6PN6JF0CPcajpBKGlTI15242a8d4g==",
+ assertNull("A null logId should return null", store.getKnownLog(null));
- "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAER3qB0NADsP1szXxe4EagrD/ryPVh" +
- "Y/azWbKyXcK12zhXnO8WH2U4QROVUMctFXLflIzw0EivdRN9t7UH1Od30w==",
-
- "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEY0ww9JqeJvzVtKNTPVb3JZa7s0ZV" +
- "duH3PpshpMS5XVoPRSjSQCph6f3HjUcM3c4N2hpa8OFbrFFy37ttUrgD+A=="
- };
- private static final String[] LOG_FILENAMES = new String[] {
- "df1c2ec11500945247a96168325ddc5c7959e8f7c6d388fc002e0bbd3f74d764",
- "84f8ae3f613b13407a75fa2893b93ab03b18d86c455fe7c241ae020033216446",
- "89baa01a445100009d8f9a238947115b30702275aafee675a7d94b6b09287619",
- "57456bffe268e49a190dce4318456034c2b4958f3c0201bed5a366737d1e74ca",
- "896c898ced4b8e6547fa351266caae4ca304f1c1ec2b623c2ee259c5452147b0"
- };
-
- private static final CTLogInfo[] LOGS;
- private static final String[] LOGS_SERIALIZED;
-
- static {
- try {
- int logCount = LOG_KEYS.length;
- LOGS = new CTLogInfo[logCount];
- LOGS_SERIALIZED = new String[logCount];
- for (int i = 0; i < logCount; i++) {
- PublicKey key = InternalUtil.readPublicKeyPem(new ByteArrayInputStream(
- ("-----BEGIN PUBLIC KEY-----\n" +
- LOG_KEYS[i] + "\n" +
- "-----END PUBLIC KEY-----\n").getBytes(StandardCharsets.US_ASCII)));
- String description = String.format("Test Log %d", i);
- String url = String.format("log%d.example.com", i);
- LOGS[i] = new CTLogInfo(key, description, url);
- LOGS_SERIALIZED[i] = String.format("description:%s\nurl:%s\nkey:%s",
- description, url, LOG_KEYS[i]);
- }
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
+ byte[] pem = ("-----BEGIN PUBLIC KEY-----\n"
+ + "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHblsqctplMVc5ramA7vSuNxUQxcomQwGAVAdnWTAWUYr"
+ + "3MgDHQW0LagJ95lB7QT75Ve6JgT2EVLOFGU7L3YrwA=="
+ + "\n-----END PUBLIC KEY-----\n")
+ .getBytes(US_ASCII);
+ ByteArrayInputStream is = new ByteArrayInputStream(pem);
+ PublicKey key = OpenSSLKey.fromPublicKeyPemInputStream(is).getPublicKey();
+ String description = "Operator 1 'Test2024' log";
+ String url = "https://operator1.example.com/logs/test2024/";
+ CTLogInfo log1 = new CTLogInfo(key, CTLogInfo.STATE_USABLE, description, url);
+ byte[] log1Id = Base64.getDecoder().decode("7s3QZNXbGs7FXLedtM0TojKHRny87N7DUUhZRnEftZs=");
+ assertEquals("An existing logId should be returned", log1, store.getKnownLog(log1Id));
}
- /* CTLogStoreImpl loads the list of logs lazily when they are first needed
- * to avoid any overhead when CT is disabled.
- * This test simply forces the logs to be loaded to make sure it doesn't
- * fail, as all of the other tests use a different log store.
- */
- public void test_getDefaultFallbackLogs() {
- CTLogInfo[] knownLogs = CTLogStoreImpl.getDefaultFallbackLogs();
- assertEquals(KnownLogs.LOG_COUNT, knownLogs.length);
- }
-
- public void test_loadLog() throws Exception {
- CTLogInfo log = CTLogStoreImpl.loadLog(
- new ByteArrayInputStream(LOGS_SERIALIZED[0].getBytes(StandardCharsets.US_ASCII)));
- assertEquals(LOGS[0], log);
-
- File testFile = writeFile(LOGS_SERIALIZED[0]);
- log = CTLogStoreImpl.loadLog(testFile);
- assertEquals(LOGS[0], log);
-
- // Empty log file, used to mask fallback logs
- assertEquals(null, CTLogStoreImpl.loadLog(new ByteArrayInputStream(new byte[0])));
- try {
- CTLogStoreImpl.loadLog(new ByteArrayInputStream(
- "randomgarbage".getBytes(StandardCharsets.US_ASCII)));
- fail("InvalidLogFileException not thrown");
- } catch (CTLogStoreImpl.InvalidLogFileException e) {}
-
- try {
- CTLogStoreImpl.loadLog(new File("/nonexistent"));
- fail("FileNotFoundException not thrown");
- } catch (FileNotFoundException e) {}
- }
-
- public void test_getKnownLog() throws Exception {
- File userDir = createTempDirectory();
- userDir.deleteOnExit();
-
- File systemDir = createTempDirectory();
- systemDir.deleteOnExit();
-
- CTLogInfo[] fallback = new CTLogInfo[] { LOGS[2], LOGS[3] };
-
- CTLogStore store = new CTLogStoreImpl(userDir, systemDir, fallback);
-
- /* Add logs 0 and 1 to the user and system directories respectively
- * Log 2 & 3 are part of the fallbacks
- * But mask log 3 with an empty file in the user directory.
- * Log 4 is not in the store
- */
- File log0File = new File(userDir, LOG_FILENAMES[0]);
- File log1File = new File(systemDir, LOG_FILENAMES[1]);
- File log3File = new File(userDir, LOG_FILENAMES[3]);
- File log4File = new File(userDir, LOG_FILENAMES[4]);
-
- writeFile(log0File, LOGS_SERIALIZED[0]);
- writeFile(log1File, LOGS_SERIALIZED[1]);
- writeFile(log3File, "");
-
- // Logs 01 are present, log 2 is in the fallback and unused, log 3 is present but masked,
- // log 4 is missing
- assertEquals(LOGS[0], store.getKnownLog(LOGS[0].getID()));
- assertEquals(LOGS[1], store.getKnownLog(LOGS[1].getID()));
- // Fallback logs are not used if the userDir is present.
- assertEquals(null, store.getKnownLog(LOGS[2].getID()));
- assertEquals(null, store.getKnownLog(LOGS[3].getID()));
- assertEquals(null, store.getKnownLog(LOGS[4].getID()));
-
- /* Test whether CTLogStoreImpl caches properly
- * Modify the files on the disk, the result of the store should not change
- * Delete log 0, mask log 1, add log 4
- */
- log0File.delete();
- writeFile(log1File, "");
- writeFile(log4File, LOGS_SERIALIZED[4]);
-
- assertEquals(LOGS[0], store.getKnownLog(LOGS[0].getID()));
- assertEquals(LOGS[1], store.getKnownLog(LOGS[1].getID()));
- assertEquals(null, store.getKnownLog(LOGS[4].getID()));
-
- // Test that fallback logs are used when the userDir doesn't exist.
- File doesntExist = new File("/doesnt/exist/");
- store = new CTLogStoreImpl(doesntExist, doesntExist, fallback);
- assertEquals(LOGS[2], store.getKnownLog(LOGS[2].getID()));
- assertEquals(LOGS[3], store.getKnownLog(LOGS[3].getID()));
- }
-
- /**
- * Create a temporary file and write to it.
- * The file will be deleted on exit.
- * @param contents The data to be written to the file
- * @return A reference to the temporary file
- */
- private File writeFile(String contents) throws IOException {
+ private File writeFile(String content) throws IOException {
File file = File.createTempFile("test", null);
file.deleteOnExit();
- writeFile(file, contents);
- return file;
- }
-
- private static void writeFile(File file, String contents) throws FileNotFoundException {
- PrintWriter writer = new PrintWriter(
- new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), UTF_8)),
- false);
- try {
- writer.write(contents);
- } finally {
- writer.close();
+ try (FileWriter fw = new FileWriter(file)) {
+ fw.write(content);
}
- }
-
- /*
- * This is NOT safe, as another process could create a file between delete() and mkdir()
- * It should be fine for tests though
- */
- private static File createTempDirectory() throws IOException {
- File folder = File.createTempFile("test", "");
- folder.delete();
- folder.mkdir();
- return folder;
+ return file;
}
}
diff --git a/publicapi/src/main/java/android/net/ssl/TEST_MAPPING b/publicapi/src/main/java/android/net/ssl/TEST_MAPPING
deleted file mode 100644
index 996e0e7..0000000
--- a/publicapi/src/main/java/android/net/ssl/TEST_MAPPING
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "presubmit": [
- {
- "name": "CtsLibcoreTestCases",
- "options": [
- {
- "include-filter": "android.net.ssl"
- }
- ]
- }
- ]
-}
\ No newline at end of file
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/AbstractConscryptSocket.java b/repackaged/common/src/main/java/com/android/org/conscrypt/AbstractConscryptSocket.java
index ea6d989..d601a50 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/AbstractConscryptSocket.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/AbstractConscryptSocket.java
@@ -718,7 +718,8 @@
@android.compat.annotation.
UnsupportedAppUsage(maxTargetSdk = dalvik.annotation.compat.VersionCodes.Q,
publicAlternatives =
- "Use {@code javax.net.ssl.SSLParameters#setApplicationProtocols(java.lang.String[])}.")
+ "Use {@code "
+ + "javax.net.ssl.SSLParameters#setApplicationProtocols(java.lang.String[])}.")
@Deprecated
abstract void
setAlpnProtocols(String[] alpnProtocols);
@@ -734,7 +735,8 @@
@android.compat.annotation.
UnsupportedAppUsage(maxTargetSdk = dalvik.annotation.compat.VersionCodes.Q,
publicAlternatives =
- "Use {@code javax.net.ssl.SSLParameters#setApplicationProtocols(java.lang.String[])}.")
+ "Use {@code "
+ + "javax.net.ssl.SSLParameters#setApplicationProtocols(java.lang.String[])}.")
@Deprecated
abstract void
setAlpnProtocols(byte[] alpnProtocols);
@@ -747,7 +749,8 @@
@android.compat.annotation.
UnsupportedAppUsage(maxTargetSdk = dalvik.annotation.compat.VersionCodes.Q,
publicAlternatives =
- "Use {@code javax.net.ssl.SSLParameters#setApplicationProtocols(java.lang.String[])}.")
+ "Use {@code "
+ + "javax.net.ssl.SSLParameters#setApplicationProtocols(java.lang.String[])}.")
@SuppressWarnings("MissingOverride") // For compiling pre Java 9.
abstract void
setApplicationProtocols(String[] protocols);
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/AddressUtils.java b/repackaged/common/src/main/java/com/android/org/conscrypt/AddressUtils.java
index bdd7c97..046e87d 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/AddressUtils.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/AddressUtils.java
@@ -26,9 +26,25 @@
/*
* Regex that matches valid IPv4 and IPv6 addresses.
*/
- private static final String IP_PATTERN =
- "^(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9]))|"
- + "(?i:(?:(?:[0-9a-f]{1,4}:){7}(?:[0-9a-f]{1,4}|:))|(?:(?:[0-9a-f]{1,4}:){6}(?::[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3})|:))|(?:(?:[0-9a-f]{1,4}:){5}(?:(?:(?::[0-9a-f]{1,4}){1,2})|:(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3})|:))|(?:(?:[0-9a-f]{1,4}:){4}(?:(?:(?::[0-9a-f]{1,4}){1,3})|(?:(?::[0-9a-f]{1,4})?:(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(?:(?:[0-9a-f]{1,4}:){3}(?:(?:(?::[0-9a-f]{1,4}){1,4})|(?:(?::[0-9a-f]{1,4}){0,2}:(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(?:(?:[0-9a-f]{1,4}:){2}(?:(?:(?::[0-9a-f]{1,4}){1,5})|(?:(?::[0-9a-f]{1,4}){0,3}:(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(?:(?:[0-9a-f]{1,4}:){1}(?:(?:(?::[0-9a-f]{1,4}){1,6})|(?:(?::[0-9a-f]{1,4}){0,4}:(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(?::(?:(?:(?::[0-9a-f]{1,4}){1,7})|(?:(?::[0-9a-f]{1,4}){0,5}:(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:)))(?:%.+)?$";
+ private static final String IP_PATTERN = "^(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){"
+ + "3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9]))|"
+ + "(?i:(?:(?:[0-9a-f]{1,4}:){7}(?:[0-9a-f]{1,4}|:))|(?:(?:[0-9a-f]{1,4}:){6}(?::[0-9a-"
+ + "f]{1,4}|(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(?:\\.(?:25[0-5]|2[0-4]["
+ + "0-9]|1[0-9][0-9]|[1-9]?[0-9])){3})|:))|(?:(?:[0-9a-f]{1,4}:){5}(?:(?:(?::[0-9a-f]{"
+ + "1,4}){1,2})|:(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(?:\\.(?:25[0-5]|2["
+ + "0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3})|:))|(?:(?:[0-9a-f]{1,4}:){4}(?:(?:(?::[0-"
+ + "9a-f]{1,4}){1,3})|(?:(?::[0-9a-f]{1,4})?:(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-"
+ + "9]?[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(?:(?:[0-"
+ + "9a-f]{1,4}:){3}(?:(?:(?::[0-9a-f]{1,4}){1,4})|(?:(?::[0-9a-f]{1,4}){0,2}:(?:(?:25["
+ + "0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|"
+ + "[1-9]?[0-9])){3}))|:))|(?:(?:[0-9a-f]{1,4}:){2}(?:(?:(?::[0-9a-f]{1,4}){1,5})|(?:("
+ + "?::[0-9a-f]{1,4}){0,3}:(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(?:\\.(?:"
+ + "25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(?:(?:[0-9a-f]{1,4}:){1}(?:"
+ + "(?:(?::[0-9a-f]{1,4}){1,6})|(?:(?::[0-9a-f]{1,4}){0,4}:(?:(?:25[0-5]|2[0-4][0-9]|"
+ + "1[0-9][0-9]|[1-9]?[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3})"
+ + ")|:))|(?::(?:(?:(?::[0-9a-f]{1,4}){1,7})|(?:(?::[0-9a-f]{1,4}){0,5}:(?:(?:25[0-5]|"
+ + "2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]"
+ + "?[0-9])){3}))|:)))(?:%.+)?$";
private static Pattern ipPattern;
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ArrayUtils.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ArrayUtils.java
index 0580889..62b2a6f 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/ArrayUtils.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ArrayUtils.java
@@ -75,4 +75,11 @@
}
return result;
}
+
+ /**
+ * Checks if given array is null or has zero elements.
+ */
+ public static <T> boolean isEmpty(T[] array) {
+ return array == null || array.length == 0;
+ }
}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ByteArray.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ByteArray.java
index 6bd104d..e6fb15d 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/ByteArray.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ByteArray.java
@@ -21,12 +21,14 @@
/**
* Byte array wrapper for hashtable use. Implements equals() and hashCode().
+ * @hide This class is not part of the Android public SDK API
*/
-final class ByteArray {
+@Internal
+public final class ByteArray {
private final byte[] bytes;
private final int hashCode;
- ByteArray(byte[] bytes) {
+ public ByteArray(byte[] bytes) {
this.bytes = bytes;
this.hashCode = Arrays.hashCode(bytes);
}
@@ -38,6 +40,9 @@
@Override
public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
if (!(o instanceof ByteArray)) {
return false;
}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptEngine.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptEngine.java
index d1152b2..7a5b112 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptEngine.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptEngine.java
@@ -441,13 +441,6 @@
handshake();
releaseResources = false;
} catch (IOException e) {
- // Write CCS errors to EventLog
- String message = e.getMessage();
- // Must match error reason string of SSL_R_UNEXPECTED_CCS (in ssl/ssl_err.c)
- if (message.contains("unexpected CCS")) {
- String logMessage = String.format("ssl_unexpected_ccs: host=%s", getPeerHost());
- Platform.logEvent(logMessage);
- }
closeAll();
throw SSLUtils.toSSLHandshakeException(e);
} finally {
@@ -1503,7 +1496,7 @@
return pendingNetResult != null
? pendingNetResult
: new SSLEngineResult(getEngineStatus(), NEED_UNWRAP,
- bytesConsumed, bytesProduced);
+ bytesConsumed, bytesProduced);
case SSL_ERROR_WANT_WRITE:
// SSL_ERROR_WANT_WRITE typically means that the underlying
// transport is not writable
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptFileDescriptorSocket.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptFileDescriptorSocket.java
index 1724e48..72b98ef 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptFileDescriptorSocket.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptFileDescriptorSocket.java
@@ -246,16 +246,6 @@
return;
}
}
-
- // Write CCS errors to EventLog
- String message = e.getMessage();
- // Must match error string of SSL_R_UNEXPECTED_CCS
- if (message.contains("unexpected CCS")) {
- String logMessage =
- String.format("ssl_unexpected_ccs: host=%s", getHostnameOrIP());
- Platform.logEvent(logMessage);
- }
-
throw e;
}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/DuckTypedHpkeSpi.java b/repackaged/common/src/main/java/com/android/org/conscrypt/DuckTypedHpkeSpi.java
index d85c3f8..f8bcc26 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/DuckTypedHpkeSpi.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/DuckTypedHpkeSpi.java
@@ -78,37 +78,37 @@
} catch (IllegalAccessException e) {
throw new IllegalStateException("DuckTypedHpkSpi internal error", e);
} catch (InvocationTargetException e) {
- if (e.getCause() instanceof RuntimeException) {
- throw (RuntimeException) e.getCause();
- }
+ if (e.getCause() instanceof RuntimeException) {
+ throw (RuntimeException) e.getCause();
+ }
throw e;
}
}
private void invokeWithPossibleInvalidKey(String methodName, Object... args)
throws InvalidKeyException {
- try {
- invoke(methodName, args);
- } catch (InvocationTargetException e) {
- Throwable cause = e.getCause();
- if (cause instanceof InvalidKeyException) {
- throw (InvalidKeyException) cause;
+ try {
+ invoke(methodName, args);
+ } catch (InvocationTargetException e) {
+ Throwable cause = e.getCause();
+ if (cause instanceof InvalidKeyException) {
+ throw (InvalidKeyException) cause;
+ }
+ throw new IllegalStateException(cause);
}
- throw new IllegalStateException(cause);
- }
}
private Object invokeWithPossibleGeneralSecurity(String methodName, Object... args)
throws GeneralSecurityException {
- try {
- return invoke(methodName, args);
- } catch (InvocationTargetException e) {
- Throwable cause = e.getCause();
- if (cause instanceof GeneralSecurityException) {
- throw (GeneralSecurityException) cause;
+ try {
+ return invoke(methodName, args);
+ } catch (InvocationTargetException e) {
+ Throwable cause = e.getCause();
+ if (cause instanceof GeneralSecurityException) {
+ throw (GeneralSecurityException) cause;
+ }
+ throw new IllegalStateException(cause);
}
- throw new IllegalStateException(cause);
- }
}
private Object invokeNoChecked(String methodName, Object... args) {
@@ -127,40 +127,40 @@
@Override
public void engineInitSender(PublicKey recipientKey, byte[] info, PrivateKey senderKey,
byte[] psk, byte[] pskId) throws InvalidKeyException {
- invokeWithPossibleInvalidKey("engineInitSender", recipientKey, info, senderKey, psk, pskId);
+ invokeWithPossibleInvalidKey("engineInitSender", recipientKey, info, senderKey, psk, pskId);
}
@Override
public void engineInitSenderForTesting(PublicKey recipientKey, byte[] info, PrivateKey senderKey,
byte[] psk, byte[] pskId, byte[] sKe) throws InvalidKeyException {
- invokeWithPossibleInvalidKey(
- "engineInitSenderForTesting", recipientKey, info, senderKey, psk, pskId, sKe);
+ invokeWithPossibleInvalidKey(
+ "engineInitSenderForTesting", recipientKey, info, senderKey, psk, pskId, sKe);
}
@Override
public void engineInitRecipient(byte[] encapsulated, PrivateKey key, byte[] info,
PublicKey senderKey, byte[] psk, byte[] psk_id) throws InvalidKeyException {
- invokeWithPossibleInvalidKey(
- "engineInitRecipient", encapsulated, key, info, senderKey, psk, psk_id);
+ invokeWithPossibleInvalidKey(
+ "engineInitRecipient", encapsulated, key, info, senderKey, psk, psk_id);
}
@Override
public byte[] engineSeal(byte[] plaintext, byte[] aad) {
- return (byte[]) invokeNoChecked("engineSeal", plaintext, aad);
+ return (byte[]) invokeNoChecked("engineSeal", plaintext, aad);
}
@Override
public byte[] engineExport(int length, byte[] exporterContext) {
- return (byte[]) invokeNoChecked("engineExport", length, exporterContext);
+ return (byte[]) invokeNoChecked("engineExport", length, exporterContext);
}
@Override
public byte[] engineOpen(byte[] ciphertext, byte[] aad) throws GeneralSecurityException {
- return (byte[]) invokeWithPossibleGeneralSecurity("engineOpen", ciphertext, aad);
+ return (byte[]) invokeWithPossibleGeneralSecurity("engineOpen", ciphertext, aad);
}
@Override
public byte[] getEncapsulated() {
- return (byte[]) invokeNoChecked("getEncapsulated");
+ return (byte[]) invokeNoChecked("getEncapsulated");
}
}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/HpkeImpl.java b/repackaged/common/src/main/java/com/android/org/conscrypt/HpkeImpl.java
index 9f95750..2c0bbab 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/HpkeImpl.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/HpkeImpl.java
@@ -131,8 +131,8 @@
checkInitialised();
long maxLength = hpkeSuite.getKdf().maxExportLength();
if (length < 0 || length > maxLength) {
- throw new IllegalArgumentException(
- "Export length must be between 0 and " + maxLength + ", but was " + length);
+ throw new IllegalArgumentException(
+ "Export length must be between 0 and " + maxLength + ", but was " + length);
}
return NativeCrypto.EVP_HPKE_CTX_export(ctx, exporterContext, length);
}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/NativeCrypto.java b/repackaged/common/src/main/java/com/android/org/conscrypt/NativeCrypto.java
index 025f3dd..8329bd1 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/NativeCrypto.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/NativeCrypto.java
@@ -380,6 +380,8 @@
static native byte[] CMAC_Final(NativeRef.CMAC_CTX ctx);
+ static native void CMAC_Reset(NativeRef.CMAC_CTX ctx);
+
// --- HMAC functions ------------------------------------------------------
static native long HMAC_CTX_new();
@@ -394,6 +396,8 @@
static native byte[] HMAC_Final(NativeRef.HMAC_CTX ctx);
+ static native void HMAC_Reset(NativeRef.HMAC_CTX ctx);
+
// --- HPKE functions ------------------------------------------------------
static native byte[] EVP_HPKE_CTX_export(
NativeRef.EVP_HPKE_CTX ctx, byte[] exporterCtx, int length);
@@ -540,8 +544,8 @@
static native byte[] X509_get_serialNumber(long x509ctx, OpenSSLX509Certificate holder);
- static native void X509_verify(long x509ctx, OpenSSLX509Certificate holder, NativeRef.EVP_PKEY pkeyCtx)
- throws BadPaddingException;
+ static native void X509_verify(long x509ctx, OpenSSLX509Certificate holder,
+ NativeRef.EVP_PKEY pkeyCtx) throws BadPaddingException, IllegalBlockSizeException;
static native byte[] get_X509_tbs_cert(long x509ctx, OpenSSLX509Certificate holder);
@@ -811,8 +815,8 @@
// --- SSL handling --------------------------------------------------------
static final String OBSOLETE_PROTOCOL_SSLV3 = "SSLv3";
- private static final String DEPRECATED_PROTOCOL_TLSV1 = "TLSv1";
- private static final String DEPRECATED_PROTOCOL_TLSV1_1 = "TLSv1.1";
+ static final String DEPRECATED_PROTOCOL_TLSV1 = "TLSv1";
+ static final String DEPRECATED_PROTOCOL_TLSV1_1 = "TLSv1.1";
private static final String SUPPORTED_PROTOCOL_TLSV1_2 = "TLSv1.2";
static final String SUPPORTED_PROTOCOL_TLSV1_3 = "TLSv1.3";
@@ -1048,9 +1052,15 @@
private static final String[] ENABLED_PROTOCOLS_TLSV1 = Platform.isTlsV1Deprecated()
? new String[0]
: new String[] {
- DEPRECATED_PROTOCOL_TLSV1,
- DEPRECATED_PROTOCOL_TLSV1_1,
- };
+ DEPRECATED_PROTOCOL_TLSV1,
+ DEPRECATED_PROTOCOL_TLSV1_1,
+ };
+
+ private static final String[] SUPPORTED_PROTOCOLS_TLSV1 = Platform.isTlsV1Supported()
+ ? new String[] {
+ DEPRECATED_PROTOCOL_TLSV1,
+ DEPRECATED_PROTOCOL_TLSV1_1,
+ } : new String[0];
/** Protocols to enable by default when "TLSv1.3" is requested. */
static final String[] TLSV13_PROTOCOLS = ArrayUtils.concatValues(
@@ -1071,12 +1081,13 @@
static final String[] TLSV1_PROTOCOLS = TLSV11_PROTOCOLS;
static final String[] DEFAULT_PROTOCOLS = TLSV13_PROTOCOLS;
- private static final String[] SUPPORTED_PROTOCOLS = new String[] {
- DEPRECATED_PROTOCOL_TLSV1,
- DEPRECATED_PROTOCOL_TLSV1_1,
+
+ // If we ever get a new protocol go look for tests which are skipped using
+ // assumeTlsV11Enabled()
+ private static final String[] SUPPORTED_PROTOCOLS = ArrayUtils.concatValues(
+ SUPPORTED_PROTOCOLS_TLSV1,
SUPPORTED_PROTOCOL_TLSV1_2,
- SUPPORTED_PROTOCOL_TLSV1_3,
- };
+ SUPPORTED_PROTOCOL_TLSV1_3);
public static String[] getDefaultProtocols() {
if (Platform.isTlsV1Deprecated()) {
@@ -1153,11 +1164,7 @@
if (protocol == null) {
throw new IllegalArgumentException("protocols contains null");
}
- if (!protocol.equals(DEPRECATED_PROTOCOL_TLSV1)
- && !protocol.equals(DEPRECATED_PROTOCOL_TLSV1_1)
- && !protocol.equals(SUPPORTED_PROTOCOL_TLSV1_2)
- && !protocol.equals(SUPPORTED_PROTOCOL_TLSV1_3)
- && !protocol.equals(OBSOLETE_PROTOCOL_SSLV3)) {
+ if (!Arrays.asList(SUPPORTED_PROTOCOLS).contains(protocol)) {
throw new IllegalArgumentException("protocol " + protocol + " is not supported");
}
}
@@ -1540,6 +1547,12 @@
throws IOException;
/**
+ * Generates a key from a password and salt using Scrypt.
+ */
+ static native byte[] Scrypt_generate_key(
+ byte[] password, byte[] salt, int n, int r, int p, int key_len);
+
+ /**
* Return {@code true} if BoringSSL has been built in FIPS mode.
*/
static native boolean usesBoringSsl_FIPS_mode();
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/NativeSsl.java b/repackaged/common/src/main/java/com/android/org/conscrypt/NativeSsl.java
index ec245f9..cf78741 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/NativeSsl.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/NativeSsl.java
@@ -309,8 +309,10 @@
if (parameters.getEnabledProtocols().length == 0 && parameters.isEnabledProtocolsFiltered) {
throw new SSLHandshakeException("No enabled protocols; "
- + NativeCrypto.OBSOLETE_PROTOCOL_SSLV3
- + " is no longer supported and was filtered from the list");
+ + NativeCrypto.OBSOLETE_PROTOCOL_SSLV3 + ", "
+ + NativeCrypto.DEPRECATED_PROTOCOL_TLSV1
+ + " and " + NativeCrypto.DEPRECATED_PROTOCOL_TLSV1_1
+ + " are no longer supported and were filtered from the list");
}
NativeCrypto.setEnabledProtocols(ssl, this, parameters.enabledProtocols);
NativeCrypto.setEnabledCipherSuites(
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLKey.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLKey.java
index bc09c81..2dd78da 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLKey.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLKey.java
@@ -32,8 +32,10 @@
/**
* Represents a BoringSSL {@code EVP_PKEY}.
+ * @hide This class is not part of the Android public SDK API
*/
-final class OpenSSLKey {
+@Internal
+public final class OpenSSLKey {
private final NativeRef.EVP_PKEY ctx;
private final boolean wrapped;
@@ -182,11 +184,6 @@
if (key instanceof OpenSSLKeyHolder) {
return ((OpenSSLKeyHolder) key).getOpenSSLKey();
}
-
- if ("RSA".equals(key.getAlgorithm())) {
- return Platform.wrapRsaKey(key);
- }
-
return null;
}
@@ -264,7 +261,7 @@
*
* @throws InvalidKeyException if parsing fails
*/
- static OpenSSLKey fromPublicKeyPemInputStream(InputStream is)
+ public static OpenSSLKey fromPublicKeyPemInputStream(InputStream is)
throws InvalidKeyException {
OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is, true);
try {
@@ -282,7 +279,7 @@
}
@android.compat.annotation.UnsupportedAppUsage
- PublicKey getPublicKey() throws NoSuchAlgorithmException {
+ public PublicKey getPublicKey() throws NoSuchAlgorithmException {
switch (NativeCrypto.EVP_PKEY_type(ctx)) {
case NativeConstants.EVP_PKEY_RSA:
return new OpenSSLRSAPublicKey(this);
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLMac.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLMac.java
index 7b3ee3b..974f08f 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLMac.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLMac.java
@@ -21,7 +21,6 @@
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
-import java.security.NoSuchAlgorithmException;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.MacSpi;
import javax.crypto.SecretKey;
@@ -33,11 +32,6 @@
@Internal
public abstract class OpenSSLMac extends MacSpi {
/**
- * The secret key used in this keyed MAC.
- */
- protected byte[] keyBytes;
-
- /**
* Holds the output size of the message digest.
*/
private final int size;
@@ -55,6 +49,11 @@
/**
* Creates and initializes the relevant BoringSSL *MAC context.
*/
+ protected abstract void initContext(byte[] keyBytes);
+
+ /**
+ * Resets the context for a new operation with the same key.
+ */
protected abstract void resetContext();
/**
@@ -78,13 +77,13 @@
throw new InvalidAlgorithmParameterException("unknown parameter type");
}
- keyBytes = key.getEncoded();
+ byte[] keyBytes = key.getEncoded();
if (keyBytes == null) {
throw new InvalidKeyException("key cannot be encoded");
}
try {
- resetContext();
+ initContext(keyBytes);
} catch (RuntimeException e) {
throw new InvalidKeyException("invalid key", e);
}
@@ -169,15 +168,19 @@
}
@Override
- protected void resetContext() {
+ protected void initContext(byte[] keyBytes) {
NativeRef.HMAC_CTX ctxLocal = new NativeRef.HMAC_CTX(NativeCrypto.HMAC_CTX_new());
- if (keyBytes != null) {
- NativeCrypto.HMAC_Init_ex(ctxLocal, keyBytes, evpMd);
- }
+ NativeCrypto.HMAC_Init_ex(ctxLocal, keyBytes, evpMd);
this.ctx = ctxLocal;
}
@Override
+ protected void resetContext() {
+ final NativeRef.HMAC_CTX ctxLocal = ctx;
+ NativeCrypto.HMAC_Reset(ctxLocal);
+ }
+
+ @Override
protected void engineUpdate(byte[] input, int offset, int len) {
final NativeRef.HMAC_CTX ctxLocal = ctx;
NativeCrypto.HMAC_Update(ctxLocal, input, offset, len);
@@ -261,15 +264,19 @@
}
@Override
- protected void resetContext() {
+ protected void initContext(byte[] keyBytes) {
NativeRef.CMAC_CTX ctxLocal = new NativeRef.CMAC_CTX(NativeCrypto.CMAC_CTX_new());
- if (keyBytes != null) {
- NativeCrypto.CMAC_Init(ctxLocal, keyBytes);
- }
+ NativeCrypto.CMAC_Init(ctxLocal, keyBytes);
this.ctx = ctxLocal;
}
@Override
+ protected void resetContext() {
+ final NativeRef.CMAC_CTX ctxLocal = ctx;
+ NativeCrypto.CMAC_Reset(ctxLocal);
+ }
+
+ @Override
protected void updateDirect(long ptr, int len) {
final NativeRef.CMAC_CTX ctxLocal = ctx;
NativeCrypto.CMAC_UpdateDirect(ctxLocal, ptr, len);
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLProvider.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLProvider.java
index 4891295..5654d81 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLProvider.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLProvider.java
@@ -224,6 +224,9 @@
/* == SecretKeyFactory == */
put("SecretKeyFactory.DESEDE", PREFIX + "DESEDESecretKeyFactory");
put("Alg.Alias.SecretKeyFactory.TDEA", "DESEDE");
+ put("SecretKeyFactory.SCRYPT", PREFIX + "ScryptSecretKeyFactory");
+ put("Alg.Alias.SecretKeyFactory.1.3.6.1.4.1.11591.4.11", "SCRYPT");
+ put("Alg.Alias.SecretKeyFactory.OID.1.3.6.1.4.1.11591.4.11", "SCRYPT");
/* == KeyAgreement == */
putECDHKeyAgreementImplClass("OpenSSLECDHKeyAgreement");
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLRSAPrivateKey.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLRSAPrivateKey.java
index 0170d1b..d74c0bd 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLRSAPrivateKey.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLRSAPrivateKey.java
@@ -97,12 +97,7 @@
return new OpenSSLRSAPrivateKey(key, params);
}
- static OpenSSLKey wrapPlatformKey(RSAPrivateKey rsaPrivateKey)
- throws InvalidKeyException {
- OpenSSLKey wrapper = Platform.wrapRsaKey(rsaPrivateKey);
- if (wrapper != null) {
- return wrapper;
- }
+ static OpenSSLKey wrapPlatformKey(RSAPrivateKey rsaPrivateKey) {
return new OpenSSLKey(NativeCrypto.getRSAPrivateKeyWrapper(rsaPrivateKey, rsaPrivateKey
.getModulus().toByteArray()), true);
}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLSocketImpl.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLSocketImpl.java
index 420d934..ef603be 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLSocketImpl.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLSocketImpl.java
@@ -160,7 +160,8 @@
@android.compat.annotation.
UnsupportedAppUsage(maxTargetSdk = dalvik.annotation.compat.VersionCodes.Q,
publicAlternatives =
- "Use {@code javax.net.ssl.SSLParameters#setApplicationProtocols(java.lang.String[])}.")
+ "Use {@code "
+ + "javax.net.ssl.SSLParameters#setApplicationProtocols(java.lang.String[])}.")
@Override
@Deprecated
public final void
@@ -188,7 +189,8 @@
@android.compat.annotation.
UnsupportedAppUsage(maxTargetSdk = dalvik.annotation.compat.VersionCodes.Q,
publicAlternatives =
- "Use {@code javax.net.ssl.SSLParameters#setApplicationProtocols(java.lang.String[])}.")
+ "Use {@code "
+ + "javax.net.ssl.SSLParameters#setApplicationProtocols(java.lang.String[])}.")
@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
@Override
@Deprecated
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLX509Certificate.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLX509Certificate.java
index b007dbc..f147175 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLX509Certificate.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLX509Certificate.java
@@ -50,6 +50,7 @@
import java.util.Set;
import java.util.TimeZone;
import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
import javax.security.auth.x500.X500Principal;
/**
@@ -384,8 +385,8 @@
NativeCrypto.X509_verify(mContext, this, pkey.getNativeRef());
} catch (RuntimeException e) {
throw new CertificateException(e);
- } catch (BadPaddingException e) {
- throw new SignatureException();
+ } catch (BadPaddingException | IllegalBlockSizeException e) {
+ throw new SignatureException(e);
}
}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/SSLParametersImpl.java b/repackaged/common/src/main/java/com/android/org/conscrypt/SSLParametersImpl.java
index ee2d88e..7c1d4a8 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/SSLParametersImpl.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/SSLParametersImpl.java
@@ -28,6 +28,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.List;
import java.util.Set;
import javax.crypto.SecretKey;
import javax.net.ssl.KeyManager;
@@ -145,8 +146,20 @@
}
// initialize the list of cipher suites and protocols enabled by default
- enabledProtocols = NativeCrypto.checkEnabledProtocols(
- protocols == null ? NativeCrypto.getDefaultProtocols() : protocols).clone();
+ if (protocols == null) {
+ enabledProtocols = NativeCrypto.getDefaultProtocols().clone();
+ } else {
+ String[] filteredProtocols =
+ filterFromProtocols(protocols, Arrays.asList(!Platform.isTlsV1Filtered()
+ ? new String[0]
+ : new String[] {
+ NativeCrypto.OBSOLETE_PROTOCOL_SSLV3,
+ NativeCrypto.DEPRECATED_PROTOCOL_TLSV1,
+ NativeCrypto.DEPRECATED_PROTOCOL_TLSV1_1,
+ }));
+ isEnabledProtocolsFiltered = protocols.length != filteredProtocols.length;
+ enabledProtocols = NativeCrypto.checkEnabledProtocols(filteredProtocols).clone();
+ }
boolean x509CipherSuitesNeeded = (x509KeyManager != null) || (x509TrustManager != null);
boolean pskCipherSuitesNeeded = pskKeyManager != null;
enabledCipherSuites = getDefaultCipherSuites(
@@ -286,7 +299,13 @@
throw new IllegalArgumentException("protocols == null");
}
String[] filteredProtocols =
- filterFromProtocols(protocols, NativeCrypto.OBSOLETE_PROTOCOL_SSLV3);
+ filterFromProtocols(protocols, Arrays.asList(!Platform.isTlsV1Filtered()
+ ? new String[0]
+ : new String[] {
+ NativeCrypto.OBSOLETE_PROTOCOL_SSLV3,
+ NativeCrypto.DEPRECATED_PROTOCOL_TLSV1,
+ NativeCrypto.DEPRECATED_PROTOCOL_TLSV1_1,
+ }));
isEnabledProtocolsFiltered = protocols.length != filteredProtocols.length;
enabledProtocols = NativeCrypto.checkEnabledProtocols(filteredProtocols).clone();
}
@@ -434,14 +453,15 @@
* This filters {@code obsoleteProtocol} from the list of {@code protocols}
* down to help with app compatibility.
*/
- private static String[] filterFromProtocols(String[] protocols, String obsoleteProtocol) {
- if (protocols.length == 1 && obsoleteProtocol.equals(protocols[0])) {
+ private static String[] filterFromProtocols(String[] protocols,
+ List<String> obsoleteProtocols) {
+ if (protocols.length == 1 && obsoleteProtocols.contains(protocols[0])) {
return EMPTY_STRING_ARRAY;
}
ArrayList<String> newProtocols = new ArrayList<String>();
for (String protocol : protocols) {
- if (!obsoleteProtocol.equals(protocol)) {
+ if (!obsoleteProtocols.contains(protocol)) {
newProtocols.add(protocol);
}
}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ScryptKeySpec.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ScryptKeySpec.java
new file mode 100644
index 0000000..d6e12dd
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ScryptKeySpec.java
@@ -0,0 +1,74 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2022 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 com.android.org.conscrypt;
+
+import java.security.spec.KeySpec;
+
+/**
+ * Mirrors the <a
+ * href="https://javadoc.io/static/org.bouncycastle/bcprov-jdk15on/1.68/org/bouncycastle/jcajce/spec/ScryptKeySpec.html">class
+ * of the same name</a> from BouncyCastle.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ScryptKeySpec implements KeySpec {
+ private final char[] password;
+ private final byte[] salt;
+ private final int costParameter;
+ private final int blockSize;
+ private final int parallelizationParameter;
+ private final int keyOutputBits;
+
+ public ScryptKeySpec(
+ char[] password,
+ byte[] salt,
+ int costParameter,
+ int blockSize,
+ int parallelizationParameter,
+ int keyOutputBits) {
+ this.password = password;
+ this.salt = salt;
+ this.costParameter = costParameter;
+ this.blockSize = blockSize;
+ this.parallelizationParameter = parallelizationParameter;
+ this.keyOutputBits = keyOutputBits;
+ }
+
+ public char[] getPassword() {
+ return password;
+ }
+
+ public byte[] getSalt() {
+ return salt;
+ }
+
+ public int getCostParameter() {
+ return costParameter;
+ }
+
+ public int getBlockSize() {
+ return blockSize;
+ }
+
+ public int getParallelizationParameter() {
+ return parallelizationParameter;
+ }
+
+ public int getKeyLength() {
+ return keyOutputBits;
+ }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ScryptSecretKeyFactory.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ScryptSecretKeyFactory.java
new file mode 100644
index 0000000..ac6b67f
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ScryptSecretKeyFactory.java
@@ -0,0 +1,132 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2022 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 com.android.org.conscrypt;
+
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.InvalidKeyException;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactorySpi;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public class ScryptSecretKeyFactory extends SecretKeyFactorySpi {
+
+ @Override
+ protected SecretKey engineGenerateSecret(KeySpec inKeySpec) throws InvalidKeySpecException {
+
+ char[] password;
+ byte[] salt;
+ int n, r, p, keyOutputBits;
+
+ if (inKeySpec instanceof ScryptKeySpec) {
+ ScryptKeySpec spec = (ScryptKeySpec) inKeySpec;
+ password = spec.getPassword();
+ salt = spec.getSalt();
+ n = spec.getCostParameter();
+ r = spec.getBlockSize();
+ p = spec.getParallelizationParameter();
+ keyOutputBits = spec.getKeyLength();
+ } else {
+ // Extract parameters from any `KeySpec` that has getters with the correct name. This
+ // allows, for example, code to use BouncyCastle's KeySpec with the Conscrypt provider.
+ try {
+ password = (char[]) getValue(inKeySpec, "getPassword");
+ salt = (byte[]) getValue(inKeySpec, "getSalt");
+ n = (int) getValue(inKeySpec, "getCostParameter");
+ r = (int) getValue(inKeySpec, "getBlockSize");
+ p = (int) getValue(inKeySpec, "getParallelizationParameter");
+ keyOutputBits = (int) getValue(inKeySpec, "getKeyLength");
+ } catch (Exception e) {
+ throw new InvalidKeySpecException("Not a valid scrypt KeySpec", e);
+ }
+ }
+
+ if (keyOutputBits % 8 != 0) {
+ throw new InvalidKeySpecException("Cannot produce fractional-byte outputs");
+ }
+
+ try {
+ return new ScryptKey(NativeCrypto.Scrypt_generate_key(
+ new String(password).getBytes("UTF-8"), salt, n, r, p, keyOutputBits / 8));
+ } catch (UnsupportedEncodingException e) {
+ // Impossible according to the Java docs: UTF-8 is always supported.
+ throw new IllegalStateException(e);
+ }
+ }
+
+ private Object getValue(KeySpec spec, String methodName)
+ throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+ Method method = spec.getClass().getMethod(methodName, (Class<?>[]) null);
+ return method.invoke(spec);
+ }
+
+ @Override
+ protected KeySpec engineGetKeySpec(
+ SecretKey secretKey, @SuppressWarnings("rawtypes") Class aClass)
+ throws InvalidKeySpecException {
+ if (secretKey == null) {
+ throw new InvalidKeySpecException("Null KeySpec");
+ }
+ throw new NotImplementedException();
+ }
+
+ @Override
+ protected SecretKey engineTranslateKey(SecretKey secretKey) throws InvalidKeyException {
+ if (secretKey == null) {
+ throw new InvalidKeyException("Null SecretKey");
+ }
+ throw new NotImplementedException();
+ }
+
+ private static class ScryptKey implements SecretKey {
+ private static final long serialVersionUID = 2024924811854189128L;
+ private final byte[] key;
+
+ public ScryptKey(byte[] key) {
+ this.key = key;
+ }
+
+ @Override
+ public String getAlgorithm() {
+ // Capitalised because BouncyCastle does it.
+ return "SCRYPT";
+ }
+
+ @Override
+ public String getFormat() {
+ return "RAW";
+ }
+
+ @Override
+ public byte[] getEncoded() {
+ return key;
+ }
+ }
+
+ private static class NotImplementedException extends RuntimeException {
+ NotImplementedException() {
+ super("Not implemented");
+ }
+ }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/TEST_MAPPING b/repackaged/common/src/main/java/com/android/org/conscrypt/TEST_MAPPING
deleted file mode 100644
index 70cd8ee..0000000
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/TEST_MAPPING
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "presubmit": [
- {
- "name": "CtsLibcoreTestCases",
- "options": [
- {
- "include-filter": "com.android.org.conscrypt"
- },
- {
- "include-filter": "libcore.java.security"
- },
- {
- "include-filter": "libcore.javax.net"
- },
- {
- "include-filter": "libcore.java.net"
- }
- ]
- }
- ]
-}
\ No newline at end of file
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ct/CTLogInfo.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/CTLogInfo.java
index 348f5cc..7f9a416 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/ct/CTLogInfo.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/CTLogInfo.java
@@ -34,12 +34,30 @@
*/
@Internal
public class CTLogInfo {
+ public static final int STATE_PENDING = 0;
+ public static final int STATE_QUALIFIED = 1;
+ public static final int STATE_USABLE = 2;
+ public static final int STATE_READONLY = 3;
+ public static final int STATE_RETIRED = 4;
+ public static final int STATE_REJECTED = 5;
+
private final byte[] logId;
private final PublicKey publicKey;
+ private final int state;
private final String description;
private final String url;
- public CTLogInfo(PublicKey publicKey, String description, String url) {
+ public CTLogInfo(PublicKey publicKey, int state, String description, String url) {
+ if (publicKey == null) {
+ throw new IllegalArgumentException("null publicKey");
+ }
+ if (description == null) {
+ throw new IllegalArgumentException("null description");
+ }
+ if (state < 0 || state > STATE_REJECTED) {
+ throw new IllegalArgumentException("invalid state value");
+ }
+
try {
this.logId = MessageDigest.getInstance("SHA-256")
.digest(publicKey.getEncoded());
@@ -49,6 +67,7 @@
}
this.publicKey = publicKey;
+ this.state = state;
this.description = description;
this.url = url;
}
@@ -72,6 +91,10 @@
return url;
}
+ public int getState() {
+ return state;
+ }
+
@Override
public boolean equals(Object other) {
if (this == other) {
@@ -82,18 +105,17 @@
}
CTLogInfo that = (CTLogInfo)other;
- return
- this.publicKey.equals(that.publicKey) &&
- this.description.equals(that.description) &&
- this.url.equals(that.url);
+ return this.state == that.state && this.description.equals(that.description)
+ && this.url.equals(that.url) && Arrays.equals(this.logId, that.logId);
}
@Override
public int hashCode() {
int hash = 1;
- hash = hash * 31 + publicKey.hashCode();
+ hash = hash * 31 + Arrays.hashCode(logId);
hash = hash * 31 + description.hashCode();
hash = hash * 31 + url.hashCode();
+ hash = hash * 31 + state;
return hash;
}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ct/TEST_MAPPING b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/TEST_MAPPING
deleted file mode 100644
index e73a39a..0000000
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/ct/TEST_MAPPING
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "presubmit": [
- {
- "name": "CtsLibcoreTestCases",
- "options": [
- {
- "include-filter": "com.android.org.conscrypt.ct"
- }
- ]
- }
- ]
-}
\ No newline at end of file
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/metrics/CipherSuite.java b/repackaged/common/src/main/java/com/android/org/conscrypt/metrics/CipherSuite.java
index ed28d69..0e03e73 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/metrics/CipherSuite.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/metrics/CipherSuite.java
@@ -65,7 +65,7 @@
TLS_CIPHER_FAILED(0xFFFF),
;
- final short id;
+ final int id;
public int getId() {
return this.id;
@@ -84,6 +84,6 @@
}
private CipherSuite(int id) {
- this.id = (short) id;
+ this.id = id;
}
}
\ No newline at end of file
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/metrics/Protocol.java b/repackaged/common/src/main/java/com/android/org/conscrypt/metrics/Protocol.java
index dda1f38..96ea739 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/metrics/Protocol.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/metrics/Protocol.java
@@ -35,7 +35,7 @@
TLS_PROTO_FAILED(0xFFFF),
;
- final byte id;
+ final int id;
public int getId() {
return this.id;
@@ -61,6 +61,6 @@
}
private Protocol(int id) {
- this.id = (byte) id;
+ this.id = id;
}
}
\ No newline at end of file
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/MacTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/MacTest.java
index d0a1c64..899343f 100644
--- a/repackaged/common/src/test/java/com/android/org/conscrypt/MacTest.java
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/MacTest.java
@@ -131,6 +131,11 @@
macBytes = generateReusingMac(algorithm, keyBytes, msgBytes);
assertArrayEquals(failMessage("Re-use Mac", baseFailMsg, macBytes),
expectedBytes, macBytes);
+
+ // Calculated using a pre-loved Mac with the same key
+ macBytes = generateReusingMacSameKey(algorithm, secretKey, msgBytes);
+ assertArrayEquals(failMessage("Re-use Mac same key", baseFailMsg, macBytes),
+ expectedBytes, macBytes);
}
}
@@ -391,6 +396,19 @@
return mac.doFinal();
}
+ private byte[] generateReusingMacSameKey(String algorithm, SecretKeySpec key, byte[] message)
+ throws Exception {
+ Mac mac = getConscryptMac(algorithm, key);
+
+ // Calculate a MAC over some other message.
+ byte[] otherMessage = new byte[message.length];
+ mac.doFinal(otherMessage);
+
+ // The MAC should now have been reset to compute a new MAC with the same
+ // key.
+ return mac.doFinal(message);
+ }
+
private Mac getConscryptMac(String algorithm) throws Exception {
return getConscryptMac(algorithm, null);
}
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/ct/CTVerifierTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/ct/CTVerifierTest.java
index d0d4265..af11b09 100644
--- a/repackaged/common/src/test/java/com/android/org/conscrypt/ct/CTVerifierTest.java
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/ct/CTVerifierTest.java
@@ -49,7 +49,7 @@
PublicKey key = TestUtils.readPublicKeyPemFile("ct-server-key-public.pem");
- final CTLogInfo log = new CTLogInfo(key, "Test Log", "foo");
+ final CTLogInfo log = new CTLogInfo(key, CTLogInfo.STATE_USABLE, "Test Log", "foo");
CTLogStore store = new CTLogStore() {
@Override
public CTLogInfo getKnownLog(byte[] logId) {
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSACrt.java b/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSACrt.java
index 762f2af..d6ea668 100644
--- a/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSACrt.java
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSACrt.java
@@ -75,19 +75,19 @@
@Test
public void javaSerialization() throws Exception {
- PrivateKey privateKey = DefaultKeys.getPrivateKey("RSA");
- assertTrue(privateKey instanceof RSAPrivateCrtKey);
+ PrivateKey privateKey = DefaultKeys.getPrivateKey("RSA");
+ assertTrue(privateKey instanceof RSAPrivateCrtKey);
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- ObjectOutputStream out = new ObjectOutputStream(bos);
- out.writeObject(privateKey);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream out = new ObjectOutputStream(bos);
+ out.writeObject(privateKey);
- ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
- ObjectInputStream in = new ObjectInputStream(bis);
- PrivateKey copy = (PrivateKey) in.readObject();
- assertTrue(copy instanceof RSAPrivateCrtKey);
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ ObjectInputStream in = new ObjectInputStream(bis);
+ PrivateKey copy = (PrivateKey) in.readObject();
+ assertTrue(copy instanceof RSAPrivateCrtKey);
- assertEquals(privateKey.getFormat(), copy.getFormat());
- assertArrayEquals(privateKey.getEncoded(), copy.getEncoded());
+ assertEquals(privateKey.getFormat(), copy.getFormat());
+ assertArrayEquals(privateKey.getEncoded(), copy.getEncoded());
}
}
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/ScryptTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/ScryptTest.java
new file mode 100644
index 0000000..b20c79d
--- /dev/null
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/ScryptTest.java
@@ -0,0 +1,202 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2022 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 com.android.org.conscrypt.javax.crypto;
+
+import static com.android.org.conscrypt.TestUtils.decodeHex;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+import com.android.org.conscrypt.ScryptKeySpec;
+import com.android.org.conscrypt.TestUtils;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.security.spec.KeySpec;
+import java.util.List;
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.SecretKeySpec;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(Parameterized.class)
+public final class ScryptTest {
+ @Parameters(name = "{0}")
+ public static String[] params() {
+ return new String[] {"SCRYPT", "1.3.6.1.4.1.11591.4.11", "OID.1.3.6.1.4.1.11591.4.11"};
+ }
+
+ @Parameter public String alias;
+
+ // One of the test vectors from RFC 7914
+ private static final char[] TEST_PASSWORD = "password".toCharArray();
+ private static final byte[] TEST_SALT = "NaCl".getBytes(StandardCharsets.UTF_8);
+ private static final int TEST_COST = 1024;
+ private static final int TEST_BLOCKSIZE = 8;
+ private static final int TEST_PARALLELIZATION = 16;
+ private static final int TEST_KEY_SIZE = 512;
+ private static final byte[] TEST_KEY =
+ decodeHex("fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b373162"
+ + "2eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640");
+
+ private final List<String[]> testVectors = readTestVectors();
+
+ // Column indices in test vector CSV file
+ private static final int PASSWORD_INDEX = 0;
+ private static final int SALT_INDEX = 1;
+ private static final int N_INDEX = 2;
+ private static final int R_INDEX = 3;
+ private static final int P_INDEX = 4;
+ private static final int KEY_INDEX = 5;
+
+ @BeforeClass
+ public static void setUp() {
+ TestUtils.assumeAllowsUnsignedCrypto();
+ }
+
+ @Test
+ public void smokeTest() throws Exception {
+ SecretKeyFactory factory = SecretKeyFactory.getInstance(alias);
+ assertEquals(alias, factory.getAlgorithm());
+
+ ScryptKeySpec spec = new ScryptKeySpec(TEST_PASSWORD, TEST_SALT, TEST_COST, TEST_BLOCKSIZE,
+ TEST_PARALLELIZATION, TEST_KEY_SIZE);
+ SecretKey key = factory.generateSecret(spec);
+ assertArrayEquals(TEST_KEY, key.getEncoded());
+
+ // Convert for use with AES
+ SecretKeySpec aesKey = makeAesKeySpec(key);
+
+ // Make sure we can actually use the result
+ checkKeyIsUsableWithAes(aesKey);
+ }
+
+ @Test
+ public void duckTypingTest() throws Exception {
+ SecretKeyFactory factory = SecretKeyFactory.getInstance(alias);
+
+ KeySpec spec = new MyPrivateKeySpec(TEST_PASSWORD, TEST_SALT, TEST_COST, TEST_BLOCKSIZE,
+ TEST_PARALLELIZATION, TEST_KEY_SIZE);
+
+ SecretKey key = factory.generateSecret(spec);
+ assertArrayEquals(TEST_KEY, key.getEncoded());
+ }
+
+ private SecretKeySpec makeAesKeySpec(SecretKey key) {
+ assertEquals("RAW", key.getFormat());
+ byte[] bytes = key.getEncoded();
+ // Truncate to first 32 bytes if necessary
+ int len = Math.min(32, bytes.length);
+ return new SecretKeySpec(bytes, 0, len, "AES");
+ }
+
+ private void checkKeyIsUsableWithAes(SecretKeySpec spec) throws Exception {
+ // Terrible encryption mode but saves messing with IVs which don't matter here.
+ Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
+
+ cipher.init(Cipher.ENCRYPT_MODE, spec);
+ byte[] input = "The quick brown fox jumps over the lazy dog".getBytes(StandardCharsets.UTF_8);
+ byte[] encrypted = cipher.doFinal(input);
+ assertNotEquals(encrypted[0], input[0]);
+
+ cipher.init(Cipher.DECRYPT_MODE, spec);
+ byte[] decrypted = cipher.doFinal(encrypted);
+ assertArrayEquals(input, decrypted);
+ }
+
+ @Test
+ public void knownAnswerTest() throws Exception {
+ for (String[] entry : testVectors) {
+ char[] password = entry[PASSWORD_INDEX].toCharArray();
+ byte[] salt = entry[SALT_INDEX].getBytes(StandardCharsets.UTF_8);
+ int n = Integer.parseInt(entry[N_INDEX]);
+ int r = Integer.parseInt(entry[R_INDEX]);
+ int p = Integer.parseInt(entry[P_INDEX]);
+ byte[] expectedBytes = decodeHex(entry[KEY_INDEX]);
+
+ ScryptKeySpec spec = new ScryptKeySpec(password, salt, n, r, p, expectedBytes.length * 8);
+ SecretKeyFactory factory = SecretKeyFactory.getInstance(alias);
+ SecretKey key = factory.generateSecret(spec);
+ assertNotNull(key);
+ assertArrayEquals(expectedBytes, key.getEncoded());
+ }
+ }
+
+ private List<String[]> readTestVectors() {
+ try {
+ return TestUtils.readCsvResource("crypto/scrypt.csv");
+
+ } catch (IOException e) {
+ throw new AssertionError("Unable to load Scrypt test vectors", e);
+ }
+ }
+
+ /**
+ * @hide This class is not part of the Android public SDK API
+ */
+ public static class MyPrivateKeySpec implements KeySpec {
+ private final char[] password;
+ private final byte[] salt;
+ private final int n;
+ private final int r;
+ private final int p;
+ private final int keyOutputBits;
+
+ public MyPrivateKeySpec(char[] password, byte[] salt, int n, int r, int p, int keyOutputBits) {
+ this.password = password;
+ this.salt = salt;
+ this.n = n;
+ this.r = r;
+ this.p = p;
+ this.keyOutputBits = keyOutputBits;
+ }
+
+ public char[] getPassword() {
+ return password;
+ }
+
+ public byte[] getSalt() {
+ return salt;
+ }
+
+ public int getCostParameter() {
+ return n;
+ }
+
+ public int getBlockSize() {
+ return r;
+ }
+
+ public int getParallelizationParameter() {
+ return p;
+ }
+
+ public int getKeyLength() {
+ return keyOutputBits;
+ }
+ }
+}
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLContextTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLContextTest.java
index 5f382d1..fedae1f 100644
--- a/repackaged/common/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLContextTest.java
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLContextTest.java
@@ -123,6 +123,16 @@
}
@Test
+ public void test_SSLContext_allProtocols() throws Exception {
+ SSLConfigurationAsserts.assertSSLContextDefaultConfiguration(SSLContext.getDefault());
+
+ for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS_ALL) {
+ SSLContext sslContext = SSLContext.getInstance(protocol);
+ sslContext.init(null, null, null);
+ }
+ }
+
+ @Test
public void test_SSLContext_pskOnlyConfiguration_defaultProviderOnly() throws Exception {
// Test the scenario where only a PSKKeyManager is provided and no TrustManagers are
// provided.
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLSocketVersionCompatibilityTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLSocketVersionCompatibilityTest.java
index 847b20a..0f3c156 100644
--- a/repackaged/common/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLSocketVersionCompatibilityTest.java
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLSocketVersionCompatibilityTest.java
@@ -20,6 +20,9 @@
import static com.android.org.conscrypt.TestUtils.UTF_8;
import static com.android.org.conscrypt.TestUtils.isLinux;
import static com.android.org.conscrypt.TestUtils.isOsx;
+import static com.android.org.conscrypt.TestUtils.isTlsV1Deprecated;
+import static com.android.org.conscrypt.TestUtils.isTlsV1Filtered;
+import static com.android.org.conscrypt.TestUtils.isTlsV1Supported;
import static com.android.org.conscrypt.TestUtils.isWindows;
import static com.android.org.conscrypt.TestUtils.osName;
import static org.junit.Assert.assertArrayEquals;
@@ -107,10 +110,14 @@
import javax.net.ssl.X509ExtendedKeyManager;
import javax.net.ssl.X509KeyManager;
import javax.net.ssl.X509TrustManager;
+import libcore.junit.util.SwitchTargetSdkVersionRule;
+import libcore.junit.util.SwitchTargetSdkVersionRule.TargetSdkVersion;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import tests.net.DelegatingSSLSocketFactory;
@@ -125,6 +132,9 @@
@RunWith(Parameterized.class)
public class SSLSocketVersionCompatibilityTest {
+ @Rule
+ public TestRule switchTargetSdkVersionRule = SwitchTargetSdkVersionRule.getInstance();
+
@Parameterized.Parameters(name = "{index}: {0} client, {1} server")
public static Iterable<Object[]> data() {
return Arrays.asList(new Object[][] {
@@ -1929,7 +1939,35 @@
}
@Test
- public void test_SSLSocket_SSLv3Unsupported() throws Exception {
+ public void test_SSLSocket_TLSv1Supported() throws Exception {
+ assumeTrue(isTlsV1Supported());
+ TestSSLContext context = new TestSSLContext.Builder()
+ .clientProtocol(clientVersion)
+ .serverProtocol(serverVersion)
+ .build();
+ final SSLSocket client =
+ (SSLSocket) context.clientContext.getSocketFactory().createSocket();
+ client.setEnabledProtocols(new String[] {"TLSv1", "TLSv1.1"});
+ assertEquals(2, client.getEnabledProtocols().length);
+ }
+
+ @TargetSdkVersion(35)
+ @Test
+ public void test_SSLSocket_SSLv3Unsupported_35() throws Exception {
+ assumeFalse(isTlsV1Filtered());
+ TestSSLContext context = new TestSSLContext.Builder()
+ .clientProtocol(clientVersion)
+ .serverProtocol(serverVersion)
+ .build();
+ final SSLSocket client =
+ (SSLSocket) context.clientContext.getSocketFactory().createSocket();
+ assertThrows(IllegalArgumentException.class, () -> client.setEnabledProtocols(new String[] {"SSLv3"}));
+ assertThrows(IllegalArgumentException.class, () -> client.setEnabledProtocols(new String[] {"SSL"}));
+ }
+
+ @TargetSdkVersion(34)
+ @Test
+ public void test_SSLSocket_SSLv3Unsupported_34() throws Exception {
TestSSLContext context = new TestSSLContext.Builder()
.clientProtocol(clientVersion)
.serverProtocol(serverVersion)
@@ -1947,6 +1985,40 @@
}
}
+ @TargetSdkVersion(34)
+ @Test
+ public void test_TLSv1Filtered_34() throws Exception {
+ TestSSLContext context = new TestSSLContext.Builder()
+ .clientProtocol(clientVersion)
+ .serverProtocol(serverVersion)
+ .build();
+ final SSLSocket client =
+ (SSLSocket) context.clientContext.getSocketFactory().createSocket();
+ client.setEnabledProtocols(new String[] {"TLSv1", "TLSv1.1", "TLSv1.2"});
+ assertEquals(1, client.getEnabledProtocols().length);
+ assertEquals("TLSv1.2", client.getEnabledProtocols()[0]);
+ }
+
+ @TargetSdkVersion(35)
+ @Test
+ public void test_TLSv1Filtered_35() throws Exception {
+ assumeFalse(isTlsV1Filtered());
+ TestSSLContext context = new TestSSLContext.Builder()
+ .clientProtocol(clientVersion)
+ .serverProtocol(serverVersion)
+ .build();
+ final SSLSocket client =
+ (SSLSocket) context.clientContext.getSocketFactory().createSocket();
+ assertThrows(IllegalArgumentException.class, () ->
+ client.setEnabledProtocols(new String[] {"TLSv1", "TLSv1.1", "TLSv1.2"}));
+ }
+
+ @Test
+ public void test_TLSv1Unsupported_notEnabled() throws Exception {
+ assumeTrue(!isTlsV1Supported());
+ assertTrue(isTlsV1Deprecated());
+ }
+
// Under some circumstances, the file descriptor socket may get finalized but still
// be reused by the JDK's built-in HTTP connection reuse code. Ensure that a
// SocketException is thrown if that happens.
diff --git a/repackaged/openjdk/src/main/java/com/android/org/conscrypt/Platform.java b/repackaged/openjdk/src/main/java/com/android/org/conscrypt/Platform.java
index 44523b1..9297eb3 100644
--- a/repackaged/openjdk/src/main/java/com/android/org/conscrypt/Platform.java
+++ b/repackaged/openjdk/src/main/java/com/android/org/conscrypt/Platform.java
@@ -345,20 +345,6 @@
}
/**
- * Wraps an old AndroidOpenSSL key instance. This is not needed on RI.
- */
- @SuppressWarnings("unused")
- static OpenSSLKey wrapRsaKey(@SuppressWarnings("unused") PrivateKey javaKey) {
- return null;
- }
-
- /**
- * Logs to the system EventLog system.
- */
- @SuppressWarnings("unused")
- static void logEvent(@SuppressWarnings("unused") String message) {}
-
- /**
* For unbundled versions, SNI is always enabled by default.
*/
@SuppressWarnings("unused")
@@ -817,4 +803,12 @@
public static boolean isTlsV1Deprecated() {
return true;
}
+
+ public static boolean isTlsV1Filtered() {
+ return false;
+ }
+
+ public static boolean isTlsV1Supported() {
+ return false;
+ }
}
diff --git a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ConscryptOpenJdkSuite.java b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ConscryptOpenJdkSuite.java
index 8b0b91d..eba53b3 100644
--- a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ConscryptOpenJdkSuite.java
+++ b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ConscryptOpenJdkSuite.java
@@ -1,4 +1,20 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2023 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 com.android.org.conscrypt;
import static com.android.org.conscrypt.TestUtils.installConscryptAsDefaultProvider;
diff --git a/repackaged/platform/src/main/java/com/android/org/conscrypt/CertBlocklistImpl.java b/repackaged/platform/src/main/java/com/android/org/conscrypt/CertBlocklistImpl.java
index 06de29a..6e4c1c3 100644
--- a/repackaged/platform/src/main/java/com/android/org/conscrypt/CertBlocklistImpl.java
+++ b/repackaged/platform/src/main/java/com/android/org/conscrypt/CertBlocklistImpl.java
@@ -25,14 +25,16 @@
import java.io.IOException;
import java.io.RandomAccessFile;
import java.math.BigInteger;
-import java.security.GeneralSecurityException;
import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -45,14 +47,35 @@
private static final Logger logger = Logger.getLogger(CertBlocklistImpl.class.getName());
private final Set<BigInteger> serialBlocklist;
- private final Set<ByteString> pubkeyBlocklist;
+ private final Set<ByteArray> sha1PubkeyBlocklist;
+ private final Set<ByteArray> sha256PubkeyBlocklist;
+ private Map<ByteArray, Boolean> cache;
+
+ /**
+ * Number of entries in the cache. The cache contains public keys which are
+ * at most 4096 bits (512 bytes) for RSA. For a cache size of 64, that is
+ * at most 512 * 64 = 32,768 bytes.
+ */
+ private static final int CACHE_SIZE = 64;
/**
* public for testing only.
*/
- public CertBlocklistImpl(Set<BigInteger> serialBlocklist, Set<ByteString> pubkeyBlocklist) {
+ public CertBlocklistImpl(Set<BigInteger> serialBlocklist, Set<ByteArray> sha1PubkeyBlocklist) {
+ this(serialBlocklist, sha1PubkeyBlocklist, Collections.emptySet());
+ }
+
+ public CertBlocklistImpl(Set<BigInteger> serialBlocklist, Set<ByteArray> sha1PubkeyBlocklist,
+ Set<ByteArray> sha256PubkeyBlocklist) {
+ this.cache = Collections.synchronizedMap(new LinkedHashMap<ByteArray, Boolean>() {
+ @Override
+ protected boolean removeEldestEntry(Map.Entry<ByteArray, Boolean> eldest) {
+ return size() > CACHE_SIZE;
+ }
+ });
this.serialBlocklist = serialBlocklist;
- this.pubkeyBlocklist = pubkeyBlocklist;
+ this.sha1PubkeyBlocklist = sha1PubkeyBlocklist;
+ this.sha256PubkeyBlocklist = sha256PubkeyBlocklist;
}
public static CertBlocklist getDefault() {
@@ -60,10 +83,14 @@
String blocklistRoot = androidData + "/misc/keychain/";
String defaultPubkeyBlocklistPath = blocklistRoot + "pubkey_blacklist.txt";
String defaultSerialBlocklistPath = blocklistRoot + "serial_blacklist.txt";
+ String defaultPubkeySha256BlocklistPath = blocklistRoot + "pubkey_sha256_blocklist.txt";
- Set<ByteString> pubkeyBlocklist = readPublicKeyBlockList(defaultPubkeyBlocklistPath);
+ Set<ByteArray> sha1PubkeyBlocklist =
+ readPublicKeyBlockList(defaultPubkeyBlocklistPath, "SHA-1");
+ Set<ByteArray> sha256PubkeyBlocklist =
+ readPublicKeyBlockList(defaultPubkeySha256BlocklistPath, "SHA-256");
Set<BigInteger> serialBlocklist = readSerialBlockList(defaultSerialBlocklistPath);
- return new CertBlocklistImpl(serialBlocklist, pubkeyBlocklist);
+ return new CertBlocklistImpl(serialBlocklist, sha1PubkeyBlocklist, sha256PubkeyBlocklist);
}
private static boolean isHex(String value) {
@@ -76,8 +103,8 @@
}
}
- private static boolean isPubkeyHash(String value) {
- if (value.length() != 40) {
+ private static boolean isPubkeyHash(String value, int expectedHashLength) {
+ if (value.length() != expectedHashLength) {
logger.log(Level.WARNING, "Invalid pubkey hash length: " + value.length());
return false;
}
@@ -133,32 +160,12 @@
}
private static Set<BigInteger> readSerialBlockList(String path) {
-
- /* Start out with a base set of known bad values.
- *
- * WARNING: Do not add short serials to this list!
- *
- * Since this currently doesn't compare the serial + issuer, you
- * should only add serials that have enough entropy here. Short
- * serials may inadvertently match a certificate that was issued
- * not in compliance with the Baseline Requirements.
+ /*
+ * Deprecated. Serials may inadvertently match a certificate that was
+ * issued not in compliance with the Baseline Requirements. Prefer
+ * using the certificate public key.
*/
- Set<BigInteger> bl = new HashSet<BigInteger>(Arrays.asList(
- // From http://src.chromium.org/viewvc/chrome/trunk/src/net/base/x509_certificate.cc?revision=78748&view=markup
- // Not a real certificate. For testing only.
- new BigInteger("077a59bcd53459601ca6907267a6dd1c", 16),
- new BigInteger("047ecbe9fca55f7bd09eae36e10cae1e", 16),
- new BigInteger("d8f35f4eb7872b2dab0692e315382fb0", 16),
- new BigInteger("b0b7133ed096f9b56fae91c874bd3ac0", 16),
- new BigInteger("9239d5348f40d1695a745470e1f23f43", 16),
- new BigInteger("e9028b9578e415dc1a710a2b88154447", 16),
- new BigInteger("d7558fdaf5f1105bb213282b707729a3", 16),
- new BigInteger("f5c86af36162f13a64f54f6dc9587c06", 16),
- new BigInteger("392a434f0e07df1f8aa305de34e0c229", 16),
- new BigInteger("3e75ced46b693021218830ae86a82a71", 16)
- ));
-
- // attempt to augment it with values taken from gservices
+ Set<BigInteger> bl = new HashSet<BigInteger>();
String serialBlocklist = readBlocklist(path);
if (!serialBlocklist.equals("")) {
for (String value : serialBlocklist.split(",", -1)) {
@@ -174,15 +181,13 @@
return Collections.unmodifiableSet(bl);
}
- private static Set<ByteString> readPublicKeyBlockList(String path) {
-
- // start out with a base set of known bad values
- Set<ByteString> bl = new HashSet<ByteString>(toByteStrings(
+ static final byte[][] SHA1_BUILTINS = {
// Blocklist test cert for CTS. The cert and key can be found in
// src/test/resources/blocklist_test_ca.pem and
// src/test/resources/blocklist_test_ca_key.pem.
"bae78e6bed65a2bf60ddedde7fd91e825865e93d".getBytes(UTF_8),
- // From http://src.chromium.org/viewvc/chrome/branches/782/src/net/base/x509_certificate.cc?r1=98750&r2=98749&pathrev=98750
+ // From
+ // http://src.chromium.org/viewvc/chrome/branches/782/src/net/base/x509_certificate.cc?r1=98750&r2=98749&pathrev=98750
// C=NL, O=DigiNotar, CN=DigiNotar Root CA/emailAddress=info@diginotar.nl
"410f36363258f30b347d12ce4863e433437806a8".getBytes(UTF_8),
// Subject: CN=DigiNotar Cyber CA
@@ -209,16 +214,49 @@
"783333c9687df63377efceddd82efa9101913e8e".getBytes(UTF_8),
// Subject: Subject: C=FR, O=DG Tr\xC3\xA9sor, CN=AC DG Tr\xC3\xA9sor SSL
// Issuer: C=FR, O=DGTPE, CN=AC DGTPE Signature Authentification
- "3ecf4bbbe46096d514bb539bb913d77aa4ef31bf".getBytes(UTF_8)
- ));
+ "3ecf4bbbe46096d514bb539bb913d77aa4ef31bf".getBytes(UTF_8),
+ };
+
+ static final byte[][] SHA256_BUILTINS = {
+ // Blocklist test cert for CTS. The cert and key can be found in
+ // src/test/resources/blocklist_test_ca2.pem and
+ // src/test/resources/blocklist_test_ca2_key.pem.
+ "809964b15e9bd312993d9984045551f503f2cf8e68f39188921ba30fe623f9fd".getBytes(UTF_8),
+ };
+
+ private static Set<ByteArray> readPublicKeyBlockList(String path, String hashType) {
+ Set<ByteArray> bl;
+
+ switch (hashType) {
+ case "SHA-1":
+ bl = new HashSet<ByteArray>(toByteArrays(SHA1_BUILTINS));
+ break;
+ case "SHA-256":
+ bl = new HashSet<ByteArray>(toByteArrays(SHA256_BUILTINS));
+ break;
+ default:
+ throw new RuntimeException(
+ "Unknown hashType: " + hashType + ". Expected SHA-1 or SHA-256");
+ }
+
+ MessageDigest md;
+ try {
+ md = MessageDigest.getInstance(hashType);
+ } catch (NoSuchAlgorithmException e) {
+ logger.log(Level.SEVERE, "Unable to get " + hashType + " MessageDigest", e);
+ return bl;
+ }
+ // The hashes are encoded with hexadecimal values. There should be
+ // twice as many characters as the digest length in bytes.
+ int hashLength = md.getDigestLength() * 2;
// attempt to augment it with values taken from gservices
String pubkeyBlocklist = readBlocklist(path);
if (!pubkeyBlocklist.equals("")) {
for (String value : pubkeyBlocklist.split(",", -1)) {
value = value.trim();
- if (isPubkeyHash(value)) {
- bl.add(new ByteString(value.getBytes(UTF_8)));
+ if (isPubkeyHash(value, hashLength)) {
+ bl.add(new ByteArray(value.getBytes(UTF_8)));
} else {
logger.log(Level.WARNING, "Tried to blocklist invalid pubkey " + value);
}
@@ -228,22 +266,46 @@
return bl;
}
- @Override
- public boolean isPublicKeyBlockListed(PublicKey publicKey) {
- byte[] encoded = publicKey.getEncoded();
+ private static boolean isPublicKeyBlockListed(
+ byte[] encodedPublicKey, Set<ByteArray> blocklist, String hashType) {
MessageDigest md;
try {
- md = MessageDigest.getInstance("SHA1");
- } catch (GeneralSecurityException e) {
- logger.log(Level.SEVERE, "Unable to get SHA1 MessageDigest", e);
+ md = MessageDigest.getInstance(hashType);
+ } catch (NoSuchAlgorithmException e) {
+ logger.log(Level.SEVERE, "Unable to get " + hashType + " MessageDigest", e);
return false;
}
- byte[] out = toHex(md.digest(encoded));
- for (ByteString blocklisted : pubkeyBlocklist) {
- if (Arrays.equals(blocklisted.bytes, out)) {
+ ByteArray out = new ByteArray(toHex(md.digest(encodedPublicKey)));
+ if (blocklist.contains(out)) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isPublicKeyBlockListed(PublicKey publicKey) {
+ byte[] encodedPublicKey = publicKey.getEncoded();
+ // cacheKey is a view on encodedPublicKey. Because it is used as a key
+ // for a Map, its underlying array (encodedPublicKey) should not be
+ // modified.
+ ByteArray cacheKey = new ByteArray(encodedPublicKey);
+ Boolean cachedResult = cache.get(cacheKey);
+ if (cachedResult != null) {
+ return cachedResult.booleanValue();
+ }
+ if (!sha1PubkeyBlocklist.isEmpty()) {
+ if (isPublicKeyBlockListed(encodedPublicKey, sha1PubkeyBlocklist, "SHA-1")) {
+ cache.put(cacheKey, true);
return true;
}
}
+ if (!sha256PubkeyBlocklist.isEmpty()) {
+ if (isPublicKeyBlockListed(encodedPublicKey, sha256PubkeyBlocklist, "SHA-256")) {
+ cache.put(cacheKey, true);
+ return true;
+ }
+ }
+ cache.put(cacheKey, false);
return false;
}
@@ -267,37 +329,11 @@
return serialBlocklist.contains(serial);
}
- private static List<ByteString> toByteStrings(byte[]... allBytes) {
- List<ByteString> byteStrings = new ArrayList<>(allBytes.length + 1);
+ private static List<ByteArray> toByteArrays(byte[]... allBytes) {
+ List<ByteArray> byteArrays = new ArrayList<>(allBytes.length + 1);
for (byte[] bytes : allBytes) {
- byteStrings.add(new ByteString(bytes));
+ byteArrays.add(new ByteArray(bytes));
}
- return byteStrings;
- }
-
- private static class ByteString {
- final byte[] bytes;
-
- public ByteString(byte[] bytes) {
- this.bytes = bytes;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
- if (!(o instanceof ByteString)) {
- return false;
- }
-
- ByteString other = (ByteString) o;
- return Arrays.equals(bytes, other.bytes);
- }
-
- @Override
- public int hashCode() {
- return Arrays.hashCode(bytes);
- }
+ return byteArrays;
}
}
diff --git a/repackaged/platform/src/main/java/com/android/org/conscrypt/InternalUtil.java b/repackaged/platform/src/main/java/com/android/org/conscrypt/InternalUtil.java
deleted file mode 100644
index bf3f043..0000000
--- a/repackaged/platform/src/main/java/com/android/org/conscrypt/InternalUtil.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-/*
- * Copyright 2017 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 com.android.org.conscrypt;
-
-import java.io.InputStream;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PublicKey;
-import com.android.org.conscrypt.OpenSSLX509CertificateFactory.ParsingException;
-
-/**
- * Helper to initialize the JNI libraries. This version runs when compiled
- * as part of the platform.
- * @hide This class is not part of the Android public SDK API
- */
-@Internal
-public final class InternalUtil {
- public static PublicKey logKeyToPublicKey(byte[] logKey)
- throws NoSuchAlgorithmException {
- try {
- return new OpenSSLKey(NativeCrypto.EVP_parse_public_key(logKey)).getPublicKey();
- } catch (ParsingException e) {
- throw new NoSuchAlgorithmException(e);
- }
- }
-
- public static PublicKey readPublicKeyPem(InputStream pem) throws InvalidKeyException, NoSuchAlgorithmException {
- return OpenSSLKey.fromPublicKeyPemInputStream(pem).getPublicKey();
- }
-
- private InternalUtil() {
- }
-}
diff --git a/repackaged/platform/src/main/java/com/android/org/conscrypt/Platform.java b/repackaged/platform/src/main/java/com/android/org/conscrypt/Platform.java
index 3ad55e2..1ab49f5 100644
--- a/repackaged/platform/src/main/java/com/android/org/conscrypt/Platform.java
+++ b/repackaged/platform/src/main/java/com/android/org/conscrypt/Platform.java
@@ -30,9 +30,11 @@
import com.android.org.conscrypt.ct.CTPolicyImpl;
import com.android.org.conscrypt.metrics.CipherSuite;
import com.android.org.conscrypt.metrics.ConscryptStatsLog;
+import com.android.org.conscrypt.metrics.OptionalMethod;
import com.android.org.conscrypt.metrics.Protocol;
import dalvik.system.BlockGuard;
import dalvik.system.CloseGuard;
+import dalvik.system.VMRuntime;
import java.io.FileDescriptor;
import java.io.IOException;
import java.lang.System;
@@ -265,35 +267,6 @@
}
}
- /**
- * Wraps an old AndroidOpenSSL key instance. This is not needed on platform
- * builds since we didn't backport, so return null.
- */
- static OpenSSLKey wrapRsaKey(PrivateKey key) {
- return null;
- }
-
- /**
- * Logs to the system EventLog system.
- */
- static void logEvent(String message) {
- try {
- Class processClass = Class.forName("android.os.Process");
- Object processInstance = processClass.newInstance();
- Method myUidMethod = processClass.getMethod("myUid", (Class[]) null);
- int uid = (Integer) myUidMethod.invoke(processInstance);
-
- Class eventLogClass = Class.forName("android.util.EventLog");
- Object eventLogInstance = eventLogClass.newInstance();
- Method writeEventMethod = eventLogClass.getMethod(
- "writeEvent", new Class[] {Integer.TYPE, Object[].class});
- writeEventMethod.invoke(eventLogInstance, 0x534e4554 /* SNET */,
- new Object[] {"conscrypt", uid, message});
- } catch (Exception e) {
- // Do not log and fail silently
- }
- }
-
static SSLEngine wrapEngine(ConscryptEngine engine) {
return new Java8EngineWrapper(engine);
}
@@ -492,6 +465,10 @@
}
static boolean isCTVerificationRequired(String hostname) {
+ if (Flags.certificateTransparencyPlatform()) {
+ return NetworkSecurityPolicy.getInstance()
+ .isCertificateTransparencyVerificationRequired(hostname);
+ }
return false;
}
@@ -571,4 +548,32 @@
public static boolean isTlsV1Deprecated() {
return true;
}
+
+ public static boolean isTlsV1Filtered() {
+ Object targetSdkVersion = getTargetSdkVersion();
+ if ((targetSdkVersion != null) && ((int) targetSdkVersion > 34))
+ return false;
+ return true;
+ }
+
+ public static boolean isTlsV1Supported() {
+ return false;
+ }
+
+ static Object getTargetSdkVersion() {
+ try {
+ Class<?> vmRuntime = Class.forName("dalvik.system.VMRuntime");
+ if (vmRuntime == null) {
+ return null;
+ }
+ OptionalMethod getSdkVersion =
+ new OptionalMethod(vmRuntime,
+ "getTargetSdkVersion");
+ return getSdkVersion.invokeStatic();
+ } catch (ClassNotFoundException e) {
+ return null;
+ } catch (NullPointerException e) {
+ return null;
+ }
+ }
}
diff --git a/repackaged/platform/src/main/java/com/android/org/conscrypt/TEST_MAPPING b/repackaged/platform/src/main/java/com/android/org/conscrypt/TEST_MAPPING
deleted file mode 100644
index 04c4062..0000000
--- a/repackaged/platform/src/main/java/com/android/org/conscrypt/TEST_MAPPING
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "imports": [
- {
- "path": "external/conscrypt/repackaged/common/src/main/java/com/android/org/conscrypt"
- }
- ]
-}
\ No newline at end of file
diff --git a/repackaged/platform/src/main/java/com/android/org/conscrypt/TrustedCertificateStore.java b/repackaged/platform/src/main/java/com/android/org/conscrypt/TrustedCertificateStore.java
index 7967ab8..6ca05b3 100644
--- a/repackaged/platform/src/main/java/com/android/org/conscrypt/TrustedCertificateStore.java
+++ b/repackaged/platform/src/main/java/com/android/org/conscrypt/TrustedCertificateStore.java
@@ -17,6 +17,7 @@
package com.android.org.conscrypt;
+import com.android.org.conscrypt.ArrayUtils;
import com.android.org.conscrypt.io.IoUtils;
import com.android.org.conscrypt.metrics.OptionalMethod;
import java.io.BufferedInputStream;
@@ -120,7 +121,7 @@
if ((System.getProperty("system.certs.enabled") != null)
&& (System.getProperty("system.certs.enabled")).equals("true"))
return false;
- if (updatableDir.exists() && !(updatableDir.list().length == 0))
+ if (updatableDir.exists() && !(ArrayUtils.isEmpty(updatableDir.list())))
return true;
return false;
}
diff --git a/repackaged/platform/src/main/java/com/android/org/conscrypt/ct/CTLogStoreImpl.java b/repackaged/platform/src/main/java/com/android/org/conscrypt/ct/CTLogStoreImpl.java
index d34b683..85fdd24 100644
--- a/repackaged/platform/src/main/java/com/android/org/conscrypt/ct/CTLogStoreImpl.java
+++ b/repackaged/platform/src/main/java/com/android/org/conscrypt/ct/CTLogStoreImpl.java
@@ -17,247 +17,168 @@
package com.android.org.conscrypt.ct;
+import static java.nio.charset.StandardCharsets.US_ASCII;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import com.android.org.conscrypt.ByteArray;
import com.android.org.conscrypt.Internal;
-import com.android.org.conscrypt.InternalUtil;
+import com.android.org.conscrypt.OpenSSLKey;
import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
-import java.util.Arrays;
+import java.util.Base64;
import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Scanner;
-import java.util.Set;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
/**
* @hide This class is not part of the Android public SDK API
*/
@Internal
public class CTLogStoreImpl implements CTLogStore {
- private static final Charset US_ASCII = StandardCharsets.US_ASCII;
+ private static final Logger logger = Logger.getLogger(CTLogStoreImpl.class.getName());
+ public static final String V3_PATH = "/misc/keychain/ct/v3/log_list.json";
+ private static final Path defaultLogList;
- /**
- * Thrown when parsing of a log file fails.
- * @hide This class is not part of the Android public SDK API
- */
- public static class InvalidLogFileException extends Exception {
- public InvalidLogFileException() {
- }
-
- public InvalidLogFileException(String message) {
- super(message);
- }
-
- public InvalidLogFileException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public InvalidLogFileException(Throwable cause) {
- super(cause);
- }
- }
-
- private static final File defaultUserLogDir;
- private static final File defaultSystemLogDir;
- // Lazy loaded by CTLogStoreImpl()
- private static volatile CTLogInfo[] defaultFallbackLogs = null;
static {
String ANDROID_DATA = System.getenv("ANDROID_DATA");
- String ANDROID_ROOT = System.getenv("ANDROID_ROOT");
- defaultUserLogDir = new File(ANDROID_DATA + "/misc/keychain/trusted_ct_logs/current/");
- defaultSystemLogDir = new File(ANDROID_ROOT + "/etc/security/ct_known_logs/");
+ defaultLogList = Paths.get(ANDROID_DATA, V3_PATH);
}
- private final File userLogDir;
- private final File systemLogDir;
- private final CTLogInfo[] fallbackLogs;
+ private enum State {
+ UNINITIALIZED,
+ LOADED,
+ NOT_FOUND,
+ MALFORMED,
+ }
- private final HashMap<ByteBuffer, CTLogInfo> logCache = new HashMap<>();
- private final Set<ByteBuffer> missingLogCache =
- Collections.synchronizedSet(new HashSet<ByteBuffer>());
+ private final Path logList;
+ private State state;
+ private String version;
+ private Map<ByteArray, CTLogInfo> logs;
public CTLogStoreImpl() {
- this(defaultUserLogDir,
- defaultSystemLogDir,
- getDefaultFallbackLogs());
+ this(defaultLogList);
}
- public CTLogStoreImpl(File userLogDir, File systemLogDir, CTLogInfo[] fallbackLogs) {
- this.userLogDir = userLogDir;
- this.systemLogDir = systemLogDir;
- this.fallbackLogs = fallbackLogs;
+ public CTLogStoreImpl(Path logList) {
+ this.state = State.UNINITIALIZED;
+ this.logList = logList;
}
@Override
public CTLogInfo getKnownLog(byte[] logId) {
- ByteBuffer buf = ByteBuffer.wrap(logId);
- CTLogInfo log = logCache.get(buf);
+ if (logId == null) {
+ return null;
+ }
+ if (!ensureLogListIsLoaded()) {
+ return null;
+ }
+ ByteArray buf = new ByteArray(logId);
+ CTLogInfo log = logs.get(buf);
if (log != null) {
return log;
}
- if (missingLogCache.contains(buf)) {
- return null;
- }
-
- log = findKnownLog(logId);
- if (log != null) {
- logCache.put(buf, log);
- } else {
- missingLogCache.add(buf);
- }
-
- return log;
- }
-
- private CTLogInfo findKnownLog(byte[] logId) {
- String filename = hexEncode(logId);
- try {
- return loadLog(new File(userLogDir, filename));
- } catch (InvalidLogFileException e) {
- return null;
- } catch (FileNotFoundException e) {
- // Ignored
- }
-
- try {
- return loadLog(new File(systemLogDir, filename));
- } catch (InvalidLogFileException e) {
- return null;
- } catch (FileNotFoundException e) {
- // Ignored
- }
-
- // If the updateable logs dont exist then use the fallback logs.
- if (!userLogDir.exists()) {
- for (CTLogInfo log: fallbackLogs) {
- if (Arrays.equals(logId, log.getID())) {
- return log;
- }
- }
- }
return null;
}
- public static CTLogInfo[] getDefaultFallbackLogs() {
- CTLogInfo[] result = defaultFallbackLogs;
- if (result == null) {
- // single-check idiom
- defaultFallbackLogs = result = createDefaultFallbackLogs();
- }
- return result;
- }
-
- private static CTLogInfo[] createDefaultFallbackLogs() {
- CTLogInfo[] logs = new CTLogInfo[KnownLogs.LOG_COUNT];
- for (int i = 0; i < KnownLogs.LOG_COUNT; i++) {
- try {
- PublicKey key = InternalUtil.logKeyToPublicKey(KnownLogs.LOG_KEYS[i]);
-
- logs[i] = new CTLogInfo(key,
- KnownLogs.LOG_DESCRIPTIONS[i],
- KnownLogs.LOG_URLS[i]);
- } catch (NoSuchAlgorithmException e) {
- throw new RuntimeException(e);
+ /* Ensures the log list is loaded.
+ * Returns true if the log list is usable.
+ */
+ private boolean ensureLogListIsLoaded() {
+ synchronized (this) {
+ if (state == State.UNINITIALIZED) {
+ state = loadLogList();
}
+ return state == State.LOADED;
}
-
- defaultFallbackLogs = logs;
- return logs;
}
- /**
- * Load a CTLogInfo from a file.
- * @throws FileNotFoundException if the file does not exist
- * @throws InvalidLogFileException if the file could not be parsed properly
- * @return a CTLogInfo or null if the file is empty
- */
- public static CTLogInfo loadLog(File file) throws FileNotFoundException,
- InvalidLogFileException {
- return loadLog(new FileInputStream(file));
- }
-
- /**
- * Load a CTLogInfo from a textual representation. Closes {@code input} upon completion
- * of loading.
- *
- * @throws InvalidLogFileException if the input could not be parsed properly
- * @return a CTLogInfo or null if the input is empty
- */
- public static CTLogInfo loadLog(InputStream input) throws InvalidLogFileException {
- final Scanner scan = new Scanner(input, "UTF-8");
- scan.useDelimiter("\n");
-
- String description = null;
- String url = null;
- String key = null;
+ private State loadLogList() {
+ byte[] content;
try {
- // If the scanner can't even read one token then the file must be empty/blank
- if (!scan.hasNext()) {
- return null;
- }
-
- while (scan.hasNext()) {
- String[] parts = scan.next().split(":", 2);
- if (parts.length < 2) {
- continue;
- }
-
- String name = parts[0];
- String value = parts[1];
- switch (name) {
- case "description":
- description = value;
- break;
- case "url":
- url = value;
- break;
- case "key":
- key = value;
- break;
+ content = Files.readAllBytes(logList);
+ } catch (IOException e) {
+ return State.NOT_FOUND;
+ }
+ if (content == null) {
+ return State.NOT_FOUND;
+ }
+ JSONObject json;
+ try {
+ json = new JSONObject(new String(content, UTF_8));
+ } catch (JSONException e) {
+ logger.log(Level.WARNING, "Unable to parse log list", e);
+ return State.MALFORMED;
+ }
+ HashMap<ByteArray, CTLogInfo> logsMap = new HashMap<>();
+ try {
+ version = json.getString("version");
+ JSONArray operators = json.getJSONArray("operators");
+ for (int i = 0; i < operators.length(); i++) {
+ JSONObject operator = operators.getJSONObject(i);
+ String operatorName = operator.getString("name");
+ JSONArray logs = operator.getJSONArray("logs");
+ for (int j = 0; j < logs.length(); j++) {
+ JSONObject log = logs.getJSONObject(j);
+ String description = log.getString("description");
+ byte[] logId = Base64.getDecoder().decode(log.getString("log_id"));
+ PublicKey key = parsePubKey(log.getString("key"));
+ JSONObject stateObject = log.getJSONObject("state");
+ int logState = parseState(stateObject.keys().next());
+ String url = log.getString("url");
+ CTLogInfo logInfo = new CTLogInfo(key, logState, description, url);
+ logsMap.put(new ByteArray(logId), logInfo);
}
}
- } finally {
- scan.close();
+ } catch (JSONException | IllegalArgumentException e) {
+ logger.log(Level.WARNING, "Unable to parse log list", e);
+ return State.MALFORMED;
}
+ this.logs = Collections.unmodifiableMap(logsMap);
+ return State.LOADED;
+ }
- if (description == null || url == null || key == null) {
- throw new InvalidLogFileException("Missing one of 'description', 'url' or 'key'");
+ private static int parseState(String state) {
+ switch (state) {
+ case "pending":
+ return CTLogInfo.STATE_PENDING;
+ case "qualified":
+ return CTLogInfo.STATE_QUALIFIED;
+ case "usable":
+ return CTLogInfo.STATE_USABLE;
+ case "readonly":
+ return CTLogInfo.STATE_READONLY;
+ case "retired":
+ return CTLogInfo.STATE_RETIRED;
+ case "rejected":
+ return CTLogInfo.STATE_REJECTED;
+ default:
+ throw new IllegalArgumentException("Unknown log state: " + state);
}
+ }
+ private static PublicKey parsePubKey(String key) {
+ byte[] pem = ("-----BEGIN PUBLIC KEY-----\n" + key + "\n-----END PUBLIC KEY-----")
+ .getBytes(US_ASCII);
PublicKey pubkey;
try {
- pubkey = InternalUtil.readPublicKeyPem(new ByteArrayInputStream(
- ("-----BEGIN PUBLIC KEY-----\n" +
- key + "\n" +
- "-----END PUBLIC KEY-----").getBytes(US_ASCII)));
- } catch (InvalidKeyException e) {
- throw new InvalidLogFileException(e);
- } catch (NoSuchAlgorithmException e) {
- throw new InvalidLogFileException(e);
+ pubkey = OpenSSLKey.fromPublicKeyPemInputStream(new ByteArrayInputStream(pem))
+ .getPublicKey();
+ } catch (InvalidKeyException | NoSuchAlgorithmException e) {
+ throw new IllegalArgumentException(e);
}
-
- return new CTLogInfo(pubkey, description, url);
- }
-
- private final static char[] HEX_DIGITS = new char[] {
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
- };
-
- private static String hexEncode(byte[] data) {
- StringBuilder sb = new StringBuilder(data.length * 2);
- for (byte b: data) {
- sb.append(HEX_DIGITS[(b >> 4) & 0x0f]);
- sb.append(HEX_DIGITS[b & 0x0f]);
- }
- return sb.toString();
+ return pubkey;
}
}
diff --git a/repackaged/platform/src/main/java/com/android/org/conscrypt/ct/KnownLogs.java b/repackaged/platform/src/main/java/com/android/org/conscrypt/ct/KnownLogs.java
deleted file mode 100644
index 7d6dca1..0000000
--- a/repackaged/platform/src/main/java/com/android/org/conscrypt/ct/KnownLogs.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-/*
- * Copyright (C) 2015 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.
- */
-
-/* This file is generated by print_log_list.py
- * https://github.com/google/certificate-transparency/blob/master/python/utilities/log_list/print_log_list.py */
-
-package com.android.org.conscrypt.ct;
-
-import com.android.org.conscrypt.Internal;
-
-/**
- * @hide This class is not part of the Android public SDK API
- */
-@Internal
-public final class KnownLogs {
- public static final int LOG_COUNT = 8;
- public static final String[] LOG_DESCRIPTIONS = new String[] {
- "Google 'Pilot' log",
- "Google 'Aviator' log",
- "DigiCert Log Server",
- "Google 'Rocketeer' log",
- "Certly.IO log",
- "Izenpe log",
- "Symantec log",
- "Venafi log",
- };
- public static final String[] LOG_URLS = new String[] {
- "ct.googleapis.com/pilot",
- "ct.googleapis.com/aviator",
- "ct1.digicert-ct.com/log",
- "ct.googleapis.com/rocketeer",
- "log.certly.io",
- "ct.izenpe.com",
- "ct.ws.symantec.com",
- "ctlog.api.venafi.com",
- };
- public static final byte[][] LOG_KEYS = new byte[][] {
- // Google 'Pilot' log
- new byte[] {
- 48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72,
- -50, 61, 3, 1, 7, 3, 66, 0, 4, 125, -88, 75, 18, 41, -128, -93, 61, -83,
- -45, 90, 119, -72, -52, -30, -120, -77, -91, -3, -15, -45, 12, -51, 24,
- 12, -24, 65, 70, -24, -127, 1, 27, 21, -31, 75, -15, 27, 98, -35, 54, 10,
- 8, 24, -70, -19, 11, 53, -124, -48, -98, 64, 60, 45, -98, -101, -126,
- 101, -67, 31, 4, 16, 65, 76, -96
- },
- // Google 'Aviator' log
- new byte[] {
- 48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72,
- -50, 61, 3, 1, 7, 3, 66, 0, 4, -41, -12, -52, 105, -78, -28, 14, -112,
- -93, -118, -22, 90, 112, 9, 79, -17, 19, 98, -48, -115, 73, 96, -1, 27,
- 64, 80, 7, 12, 109, 113, -122, -38, 37, 73, -115, 101, -31, 8, 13, 71,
- 52, 107, -67, 39, -68, -106, 33, 62, 52, -11, -121, 118, 49, -79, 127,
- 29, -55, -123, 59, 13, -9, 31, 63, -23
- },
- // DigiCert Log Server
- new byte[] {
- 48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72,
- -50, 61, 3, 1, 7, 3, 66, 0, 4, 2, 70, -59, -66, 27, -69, -126, 64, 22,
- -24, -63, -46, -84, 25, 105, 19, 89, -8, -8, 112, -123, 70, 64, -71, 56,
- -80, 35, -126, -88, 100, 76, 127, -65, -69, 52, -97, 74, 95, 40, -118,
- -49, 25, -60, 0, -10, 54, 6, -109, 101, -19, 76, -11, -87, 33, 98, 90,
- -40, -111, -21, 56, 36, 64, -84, -24
- },
- // Google 'Rocketeer' log
- new byte[] {
- 48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72,
- -50, 61, 3, 1, 7, 3, 66, 0, 4, 32, 91, 24, -56, 60, -63, -117, -77, 49,
- 8, 0, -65, -96, -112, 87, 43, -73, 71, -116, 111, -75, 104, -80, -114,
- -112, 120, -23, -96, 115, -22, 79, 40, 33, 46, -100, -64, -12, 22, 27,
- -86, -7, -43, -41, -87, -128, -61, 78, 47, 82, 60, -104, 1, 37, 70, 36,
- 37, 40, 35, 119, 45, 5, -62, 64, 122
- },
- // Certly.IO log
- new byte[] {
- 48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72,
- -50, 61, 3, 1, 7, 3, 66, 0, 4, 11, 35, -53, -123, 98, -104, 97, 72, 4,
- 115, -21, 84, 93, -13, -48, 7, -116, 45, 25, 45, -116, 54, -11, -21,
- -113, 1, 66, 10, 124, -104, 38, 39, -63, -75, -35, -110, -109, -80, -82,
- -8, -101, 61, 12, -40, 76, 78, 29, -7, 21, -5, 71, 104, 123, -70, 102,
- -73, 37, -100, -48, 74, -62, 102, -37, 72
- },
- // Izenpe log
- new byte[] {
- 48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72,
- -50, 61, 3, 1, 7, 3, 66, 0, 4, 39, 100, 57, 12, 45, -36, 80, 24, -8, 33,
- 0, -94, 14, -19, 44, -22, 62, 117, -70, -97, -109, 100, 9, 0, 17, -60,
- 17, 23, -85, 92, -49, 15, 116, -84, -75, -105, -112, -109, 0, 91, -72,
- -21, -9, 39, 61, -39, -78, 10, -127, 95, 47, 13, 117, 56, -108, 55, -103,
- 30, -10, 7, 118, -32, -18, -66
- },
- // Symantec log
- new byte[] {
- 48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72,
- -50, 61, 3, 1, 7, 3, 66, 0, 4, -106, -22, -84, 28, 70, 12, 27, 85, -36,
- 13, -4, -75, -108, 39, 70, 87, 66, 112, 58, 105, 24, -30, -65, 59, -60,
- -37, -85, -96, -12, -74, 108, -64, 83, 63, 77, 66, 16, 51, -16, 88, -105,
- -113, 107, -66, 114, -12, 42, -20, 28, 66, -86, 3, 47, 26, 126, 40, 53,
- 118, -103, 8, 61, 33, 20, -122
- },
- // Venafi log
- new byte[] {
- 48, -126, 1, 34, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 1, 5, 0,
- 3, -126, 1, 15, 0, 48, -126, 1, 10, 2, -126, 1, 1, 0, -94, 90, 72, 31,
- 23, 82, -107, 53, -53, -93, 91, 58, 31, 83, -126, 118, -108, -93, -1,
- -128, -14, 28, 55, 60, -64, -79, -67, -63, 89, -117, -85, 45, 101, -109,
- -41, -13, -32, 4, -43, -102, 111, -65, -42, 35, 118, 54, 79, 35, -103,
- -53, 84, 40, -83, -116, 21, 75, 101, 89, 118, 65, 74, -100, -90, -9, -77,
- 59, 126, -79, -91, 73, -92, 23, 81, 108, -128, -36, 42, -112, 80, 75,
- -120, 36, -23, -91, 18, 50, -109, 4, 72, -112, 2, -6, 95, 14, 48, -121,
- -114, 85, 118, 5, -18, 42, 76, -50, -93, 106, 105, 9, 110, 37, -83, -126,
- 118, 15, -124, -110, -6, 56, -42, -122, 78, 36, -113, -101, -80, 114,
- -53, -98, -30, 107, 63, -31, 109, -55, 37, 117, 35, -120, -95, 24, 88, 6,
- 35, 51, 120, -38, 0, -48, 56, -111, 103, -46, -90, 125, 39, -105, 103,
- 90, -63, -13, 47, 23, -26, -22, -46, 91, -24, -127, -51, -3, -110, 104,
- -25, -13, 6, -16, -23, 114, -124, -18, 1, -91, -79, -40, 51, -38, -50,
- -125, -91, -37, -57, -49, -42, 22, 126, -112, 117, 24, -65, 22, -36, 50,
- 59, 109, -115, -85, -126, 23, 31, -119, 32, -115, 29, -102, -26, 77, 35,
- 8, -33, 120, 111, -58, 5, -65, 95, -82, -108, -105, -37, 95, 100, -44,
- -18, 22, -117, -93, -124, 108, 113, 43, -15, -85, 127, 93, 13, 50, -18,
- 4, -30, -112, -20, 65, -97, -5, 57, -63, 2, 3, 1, 0, 1
- },
- };
-}
diff --git a/repackaged/platform/src/main/java/com/android/org/conscrypt/ct/TEST_MAPPING b/repackaged/platform/src/main/java/com/android/org/conscrypt/ct/TEST_MAPPING
deleted file mode 100644
index 34120cb..0000000
--- a/repackaged/platform/src/main/java/com/android/org/conscrypt/ct/TEST_MAPPING
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "imports": [
- {
- "path": "external/conscrypt/repackaged/common/src/main/java/com/android/org/conscrypt/ct"
- }
- ]
-}
\ No newline at end of file
diff --git a/repackaged/platform/src/test/java/com/android/org/conscrypt/CertBlocklistTest.java b/repackaged/platform/src/test/java/com/android/org/conscrypt/CertBlocklistTest.java
index c970f22..d0a37c8 100644
--- a/repackaged/platform/src/test/java/com/android/org/conscrypt/CertBlocklistTest.java
+++ b/repackaged/platform/src/test/java/com/android/org/conscrypt/CertBlocklistTest.java
@@ -33,6 +33,7 @@
public class CertBlocklistTest extends TestCase {
private static final String BLOCKLIST_CA = "test_blocklist_ca.pem";
+ private static final String BLOCKLIST_CA2 = "test_blocklist_ca2.pem";
private static final String BLOCKLISTED_CHAIN = "blocklist_test_chain.pem";
private static final String BLOCKLIST_FALLBACK_VALID_CA = "blocklist_test_valid_ca.pem";
private static final String BLOCKLISTED_VALID_CHAIN = "blocklist_test_valid_chain.pem";
@@ -47,6 +48,15 @@
}
/**
+ * Ensure that the test blocklisted CA 2 is actually blocklisted by default.
+ */
+ public void testBlocklistedPublicKeySHA256() throws Exception {
+ X509Certificate blocklistedCa = loadCertificate(BLOCKLIST_CA2);
+ CertBlocklist blocklist = CertBlocklistImpl.getDefault();
+ assertTrue(blocklist.isPublicKeyBlockListed(blocklistedCa.getPublicKey()));
+ }
+
+ /**
* Check that the blocklisted CA is rejected even if it used as a root of trust
*/
public void testBlocklistedCaUntrusted() throws Exception {
diff --git a/repackaged/platform/src/test/java/com/android/org/conscrypt/ct/CTLogStoreImplTest.java b/repackaged/platform/src/test/java/com/android/org/conscrypt/ct/CTLogStoreImplTest.java
index c7e6efa..d240c01 100644
--- a/repackaged/platform/src/test/java/com/android/org/conscrypt/ct/CTLogStoreImplTest.java
+++ b/repackaged/platform/src/test/java/com/android/org/conscrypt/ct/CTLogStoreImplTest.java
@@ -17,192 +17,122 @@
package com.android.org.conscrypt.ct;
+import static java.nio.charset.StandardCharsets.US_ASCII;
import static java.nio.charset.StandardCharsets.UTF_8;
-import com.android.org.conscrypt.InternalUtil;
-import java.io.BufferedWriter;
+import com.android.org.conscrypt.OpenSSLKey;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
+import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
-import java.nio.charset.StandardCharsets;
import java.security.PublicKey;
+import java.util.Base64;
import junit.framework.TestCase;
/**
* @hide This class is not part of the Android public SDK API
*/
public class CTLogStoreImplTest extends TestCase {
- private static final String[] LOG_KEYS = new String[] {
- "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmXg8sUUzwBYaWrRb+V0IopzQ6o3U" +
- "yEJ04r5ZrRXGdpYM8K+hB0pXrGRLI0eeWz+3skXrS0IO83AhA3GpRL6s6w==",
+ public void test_loadLogList() throws Exception {
+ // clang-format off
+ String content = "" +
+"{" +
+" \"version\": \"1.1\"," +
+" \"log_list_timestamp\": \"2024-01-01T11:55:12Z\"," +
+" \"operators\": [" +
+" {" +
+" \"name\": \"Operator 1\"," +
+" \"email\": [\"ct@operator1.com\"]," +
+" \"logs\": [" +
+" {" +
+" \"description\": \"Operator 1 'Test2024' log\"," +
+" \"log_id\": \"7s3QZNXbGs7FXLedtM0TojKHRny87N7DUUhZRnEftZs=\"," +
+" \"key\": \"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHblsqctplMVc5ramA7vSuNxUQxcomQwGAVAdnWTAWUYr3MgDHQW0LagJ95lB7QT75Ve6JgT2EVLOFGU7L3YrwA==\"," +
+" \"url\": \"https://operator1.example.com/logs/test2024/\"," +
+" \"mmd\": 86400," +
+" \"state\": {" +
+" \"usable\": {" +
+" \"timestamp\": \"2022-11-01T18:54:00Z\"" +
+" }" +
+" }," +
+" \"temporal_interval\": {" +
+" \"start_inclusive\": \"2024-01-01T00:00:00Z\"," +
+" \"end_exclusive\": \"2025-01-01T00:00:00Z\"" +
+" }" +
+" }," +
+" {" +
+" \"description\": \"Operator 1 'Test2025' log\"," +
+" \"log_id\": \"TnWjJ1yaEMM4W2zU3z9S6x3w4I4bjWnAsfpksWKaOd8=\"," +
+" \"key\": \"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIIKh+WdoqOTblJji4WiH5AltIDUzODyvFKrXCBjw/Rab0/98J4LUh7dOJEY7+66+yCNSICuqRAX+VPnV8R1Fmg==\"," +
+" \"url\": \"https://operator1.example.com/logs/test2025/\"," +
+" \"mmd\": 86400," +
+" \"state\": {" +
+" \"usable\": {" +
+" \"timestamp\": \"2023-11-26T12:00:00Z\"" +
+" }" +
+" }," +
+" \"temporal_interval\": {" +
+" \"start_inclusive\": \"2025-01-01T00:00:00Z\"," +
+" \"end_exclusive\": \"2025-07-01T00:00:00Z\"" +
+" }" +
+" }" +
+" ]" +
+" }," +
+" {" +
+" \"name\": \"Operator 2\"," +
+" \"email\": [\"ct@operator2.com\"]," +
+" \"logs\": [" +
+" {" +
+" \"description\": \"Operator 2 'Test2024' Log\"," +
+" \"log_id\": \"2ra/az+1tiKfm8K7XGvocJFxbLtRhIU0vaQ9MEjX+6s=\"," +
+" \"key\": \"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEd7Gbe4/mizX+OpIpLayKjVGKJfyTttegiyk3cR0zyswz6ii5H+Ksw6ld3Ze+9p6UJd02gdHrXSnDK0TxW8oVSA==\"," +
+" \"url\": \"https://operator2.example.com/logs/test2024/\"," +
+" \"mmd\": 86400," +
+" \"state\": {" +
+" \"usable\": {" +
+" \"timestamp\": \"2022-11-30T17:00:00Z\"" +
+" }" +
+" }," +
+" \"temporal_interval\": {" +
+" \"start_inclusive\": \"2024-01-01T00:00:00Z\"," +
+" \"end_exclusive\": \"2025-01-01T00:00:00Z\"" +
+" }" +
+" }" +
+" ]" +
+" }" +
+" ]" +
+"}";
+ // clang-format on
- "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAErEULmlBnX9L/+AK20hLYzPMFozYx" +
- "pP0Wm1ylqGkPEwuDKn9DSpNSOym49SN77BLGuAXu9twOW/qT+ddIYVBEIw==",
+ File logList = writeFile(content);
+ CTLogStore store = new CTLogStoreImpl(logList.toPath());
- "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEP6PGcXmjlyCBz2ZFUuUjrgbZLaEF" +
- "gfLUkt2cEqlSbb4vTuB6WWmgC9h0L6PN6JF0CPcajpBKGlTI15242a8d4g==",
+ assertNull("A null logId should return null", store.getKnownLog(null));
- "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAER3qB0NADsP1szXxe4EagrD/ryPVh" +
- "Y/azWbKyXcK12zhXnO8WH2U4QROVUMctFXLflIzw0EivdRN9t7UH1Od30w==",
-
- "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEY0ww9JqeJvzVtKNTPVb3JZa7s0ZV" +
- "duH3PpshpMS5XVoPRSjSQCph6f3HjUcM3c4N2hpa8OFbrFFy37ttUrgD+A=="
- };
- private static final String[] LOG_FILENAMES = new String[] {
- "df1c2ec11500945247a96168325ddc5c7959e8f7c6d388fc002e0bbd3f74d764",
- "84f8ae3f613b13407a75fa2893b93ab03b18d86c455fe7c241ae020033216446",
- "89baa01a445100009d8f9a238947115b30702275aafee675a7d94b6b09287619",
- "57456bffe268e49a190dce4318456034c2b4958f3c0201bed5a366737d1e74ca",
- "896c898ced4b8e6547fa351266caae4ca304f1c1ec2b623c2ee259c5452147b0"
- };
-
- private static final CTLogInfo[] LOGS;
- private static final String[] LOGS_SERIALIZED;
-
- static {
- try {
- int logCount = LOG_KEYS.length;
- LOGS = new CTLogInfo[logCount];
- LOGS_SERIALIZED = new String[logCount];
- for (int i = 0; i < logCount; i++) {
- PublicKey key = InternalUtil.readPublicKeyPem(new ByteArrayInputStream(
- ("-----BEGIN PUBLIC KEY-----\n" + LOG_KEYS[i] + "\n"
- + "-----END PUBLIC KEY-----\n")
- .getBytes(StandardCharsets.US_ASCII)));
- String description = String.format("Test Log %d", i);
- String url = String.format("log%d.example.com", i);
- LOGS[i] = new CTLogInfo(key, description, url);
- LOGS_SERIALIZED[i] = String.format("description:%s\nurl:%s\nkey:%s",
- description, url, LOG_KEYS[i]);
- }
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
+ byte[] pem = ("-----BEGIN PUBLIC KEY-----\n"
+ + "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHblsqctplMVc5ramA7vSuNxUQxcomQwGAVAdnWTAWUYr"
+ + "3MgDHQW0LagJ95lB7QT75Ve6JgT2EVLOFGU7L3YrwA=="
+ + "\n-----END PUBLIC KEY-----\n")
+ .getBytes(US_ASCII);
+ ByteArrayInputStream is = new ByteArrayInputStream(pem);
+ PublicKey key = OpenSSLKey.fromPublicKeyPemInputStream(is).getPublicKey();
+ String description = "Operator 1 'Test2024' log";
+ String url = "https://operator1.example.com/logs/test2024/";
+ CTLogInfo log1 = new CTLogInfo(key, CTLogInfo.STATE_USABLE, description, url);
+ byte[] log1Id = Base64.getDecoder().decode("7s3QZNXbGs7FXLedtM0TojKHRny87N7DUUhZRnEftZs=");
+ assertEquals("An existing logId should be returned", log1, store.getKnownLog(log1Id));
}
- /* CTLogStoreImpl loads the list of logs lazily when they are first needed
- * to avoid any overhead when CT is disabled.
- * This test simply forces the logs to be loaded to make sure it doesn't
- * fail, as all of the other tests use a different log store.
- */
- public void test_getDefaultFallbackLogs() {
- CTLogInfo[] knownLogs = CTLogStoreImpl.getDefaultFallbackLogs();
- assertEquals(KnownLogs.LOG_COUNT, knownLogs.length);
- }
-
- public void test_loadLog() throws Exception {
- CTLogInfo log = CTLogStoreImpl.loadLog(
- new ByteArrayInputStream(LOGS_SERIALIZED[0].getBytes(StandardCharsets.US_ASCII)));
- assertEquals(LOGS[0], log);
-
- File testFile = writeFile(LOGS_SERIALIZED[0]);
- log = CTLogStoreImpl.loadLog(testFile);
- assertEquals(LOGS[0], log);
-
- // Empty log file, used to mask fallback logs
- assertEquals(null, CTLogStoreImpl.loadLog(new ByteArrayInputStream(new byte[0])));
- try {
- CTLogStoreImpl.loadLog(
- new ByteArrayInputStream("randomgarbage".getBytes(StandardCharsets.US_ASCII)));
- fail("InvalidLogFileException not thrown");
- } catch (CTLogStoreImpl.InvalidLogFileException e) {}
-
- try {
- CTLogStoreImpl.loadLog(new File("/nonexistent"));
- fail("FileNotFoundException not thrown");
- } catch (FileNotFoundException e) {}
- }
-
- public void test_getKnownLog() throws Exception {
- File userDir = createTempDirectory();
- userDir.deleteOnExit();
-
- File systemDir = createTempDirectory();
- systemDir.deleteOnExit();
-
- CTLogInfo[] fallback = new CTLogInfo[] { LOGS[2], LOGS[3] };
-
- CTLogStore store = new CTLogStoreImpl(userDir, systemDir, fallback);
-
- /* Add logs 0 and 1 to the user and system directories respectively
- * Log 2 & 3 are part of the fallbacks
- * But mask log 3 with an empty file in the user directory.
- * Log 4 is not in the store
- */
- File log0File = new File(userDir, LOG_FILENAMES[0]);
- File log1File = new File(systemDir, LOG_FILENAMES[1]);
- File log3File = new File(userDir, LOG_FILENAMES[3]);
- File log4File = new File(userDir, LOG_FILENAMES[4]);
-
- writeFile(log0File, LOGS_SERIALIZED[0]);
- writeFile(log1File, LOGS_SERIALIZED[1]);
- writeFile(log3File, "");
-
- // Logs 01 are present, log 2 is in the fallback and unused, log 3 is present but masked,
- // log 4 is missing
- assertEquals(LOGS[0], store.getKnownLog(LOGS[0].getID()));
- assertEquals(LOGS[1], store.getKnownLog(LOGS[1].getID()));
- // Fallback logs are not used if the userDir is present.
- assertEquals(null, store.getKnownLog(LOGS[2].getID()));
- assertEquals(null, store.getKnownLog(LOGS[3].getID()));
- assertEquals(null, store.getKnownLog(LOGS[4].getID()));
-
- /* Test whether CTLogStoreImpl caches properly
- * Modify the files on the disk, the result of the store should not change
- * Delete log 0, mask log 1, add log 4
- */
- log0File.delete();
- writeFile(log1File, "");
- writeFile(log4File, LOGS_SERIALIZED[4]);
-
- assertEquals(LOGS[0], store.getKnownLog(LOGS[0].getID()));
- assertEquals(LOGS[1], store.getKnownLog(LOGS[1].getID()));
- assertEquals(null, store.getKnownLog(LOGS[4].getID()));
-
- // Test that fallback logs are used when the userDir doesn't exist.
- File doesntExist = new File("/doesnt/exist/");
- store = new CTLogStoreImpl(doesntExist, doesntExist, fallback);
- assertEquals(LOGS[2], store.getKnownLog(LOGS[2].getID()));
- assertEquals(LOGS[3], store.getKnownLog(LOGS[3].getID()));
- }
-
- /**
- * Create a temporary file and write to it.
- * The file will be deleted on exit.
- * @param contents The data to be written to the file
- * @return A reference to the temporary file
- */
- private File writeFile(String contents) throws IOException {
+ private File writeFile(String content) throws IOException {
File file = File.createTempFile("test", null);
file.deleteOnExit();
- writeFile(file, contents);
+ try (FileWriter fw = new FileWriter(file)) {
+ fw.write(content);
+ }
return file;
}
-
- private static void writeFile(File file, String contents) throws FileNotFoundException {
- PrintWriter writer = new PrintWriter(
- new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), UTF_8)),
- false);
- try {
- writer.write(contents);
- } finally {
- writer.close();
- }
- }
-
- /*
- * This is NOT safe, as another process could create a file between delete() and mkdir()
- * It should be fine for tests though
- */
- private static File createTempDirectory() throws IOException {
- File folder = File.createTempFile("test", "");
- folder.delete();
- folder.mkdir();
- return folder;
- }
}
-
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/ChannelType.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/ChannelType.java
index a1a77c1..bc658d6 100644
--- a/repackaged/testing/src/main/java/com/android/org/conscrypt/ChannelType.java
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/ChannelType.java
@@ -40,24 +40,24 @@
public enum ChannelType {
NONE {
@Override
- SSLSocket newClientSocket(SSLSocketFactory factory, InetAddress address, int port)
+ public SSLSocket newClientSocket(SSLSocketFactory factory, InetAddress address, int port)
throws IOException {
return clientMode(factory.createSocket(address, port));
}
@Override
- ServerSocket newServerSocket(SSLServerSocketFactory factory) throws IOException {
+ public ServerSocket newServerSocket(SSLServerSocketFactory factory) throws IOException {
return factory.createServerSocket(0, 50, InetAddress.getLoopbackAddress());
}
@Override
- SSLSocket accept(ServerSocket socket, SSLSocketFactory unused) throws IOException {
+ public SSLSocket accept(ServerSocket socket, SSLSocketFactory unused) throws IOException {
return serverMode(socket.accept());
}
},
NO_CHANNEL {
@Override
- SSLSocket newClientSocket(SSLSocketFactory factory, InetAddress address, int port)
+ public SSLSocket newClientSocket(SSLSocketFactory factory, InetAddress address, int port)
throws IOException {
Socket wrapped = new Socket(address, port);
assertNull(wrapped.getChannel());
@@ -66,13 +66,13 @@
}
@Override
- ServerSocket newServerSocket(SSLServerSocketFactory unused) throws IOException {
+ public ServerSocket newServerSocket(SSLServerSocketFactory unused) throws IOException {
return ServerSocketFactory.getDefault().createServerSocket(
0, 50, InetAddress.getLoopbackAddress());
}
@Override
- SSLSocket accept(ServerSocket serverSocket, SSLSocketFactory factory) throws IOException {
+ public SSLSocket accept(ServerSocket serverSocket, SSLSocketFactory factory) throws IOException {
assertFalse(serverSocket instanceof SSLServerSocket);
Socket wrapped = serverSocket.accept();
assertNull(wrapped.getChannel());
@@ -83,21 +83,21 @@
},
CHANNEL {
@Override
- SSLSocket newClientSocket(SSLSocketFactory factory, InetAddress address, int port)
+ public SSLSocket newClientSocket(SSLSocketFactory factory, InetAddress address, int port)
throws IOException {
Socket wrapped = SocketChannel.open(new InetSocketAddress(address, port)).socket();
return clientMode(factory.createSocket(wrapped, address.getHostName(), port, true));
}
@Override
- ServerSocket newServerSocket(SSLServerSocketFactory unused) throws IOException {
+ public ServerSocket newServerSocket(SSLServerSocketFactory unused) throws IOException {
return ServerSocketChannel.open()
.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0))
.socket();
}
@Override
- SSLSocket accept(ServerSocket serverSocket, SSLSocketFactory factory) throws IOException {
+ public SSLSocket accept(ServerSocket serverSocket, SSLSocketFactory factory) throws IOException {
assertFalse(serverSocket instanceof SSLServerSocket);
ServerSocketChannel serverChannel = serverSocket.getChannel();
@@ -113,10 +113,10 @@
}
};
- abstract SSLSocket newClientSocket(SSLSocketFactory factory, InetAddress address, int port)
+ public abstract SSLSocket newClientSocket(SSLSocketFactory factory, InetAddress address, int port)
throws IOException;
- abstract ServerSocket newServerSocket(SSLServerSocketFactory factory) throws IOException;
- abstract SSLSocket accept(ServerSocket socket, SSLSocketFactory factory) throws IOException;
+ public abstract ServerSocket newServerSocket(SSLServerSocketFactory factory) throws IOException;
+ public abstract SSLSocket accept(ServerSocket socket, SSLSocketFactory factory) throws IOException;
private static SSLSocket clientMode(Socket socket) {
SSLSocket sslSocket = (SSLSocket) socket;
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/TestUtils.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/TestUtils.java
index c98a1ef..44c4625 100644
--- a/repackaged/testing/src/main/java/com/android/org/conscrypt/TestUtils.java
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/TestUtils.java
@@ -325,7 +325,7 @@
}
}
- static SSLSocketFactory setUseEngineSocket(
+ public static SSLSocketFactory setUseEngineSocket(
SSLSocketFactory conscryptFactory, boolean useEngineSocket) {
try {
Class<?> clazz = conscryptClass("Conscrypt");
@@ -338,7 +338,7 @@
}
}
- static SSLServerSocketFactory setUseEngineSocket(
+ public static SSLServerSocketFactory setUseEngineSocket(
SSLServerSocketFactory conscryptFactory, boolean useEngineSocket) {
try {
Class<?> clazz = conscryptClass("Conscrypt");
@@ -478,12 +478,12 @@
return msg;
}
- static SSLContext newClientSslContext(Provider provider) {
+ public static SSLContext newClientSslContext(Provider provider) {
SSLContext context = newContext(provider);
return initClientSslContext(context);
}
- static SSLContext newServerSslContext(Provider provider) {
+ public static SSLContext newServerSslContext(Provider provider) {
SSLContext context = newContext(provider);
return initServerSslContext(context);
}
@@ -839,4 +839,32 @@
throw new IllegalStateException("Reflection failure", e);
}
}
+
+ // Find base method via reflection due to possible version skew on Android
+ // and visibility issues when building with Gradle.
+ public static boolean isTlsV1Supported() {
+ try {
+ return (Boolean) conscryptClass("Platform")
+ .getDeclaredMethod("isTlsV1Supported")
+ .invoke(null);
+ } catch (NoSuchMethodException e) {
+ return true;
+ } catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException e) {
+ throw new IllegalStateException("Reflection failure", e);
+ }
+ }
+
+ // Find base method via reflection due to possible version skew on Android
+ // and visibility issues when building with Gradle.
+ public static boolean isTlsV1Filtered() {
+ try {
+ return (Boolean) conscryptClass("Platform")
+ .getDeclaredMethod("isTlsV1Filtered")
+ .invoke(null);
+ } catch (NoSuchMethodException e) {
+ return true;
+ } catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException e) {
+ throw new IllegalStateException("Reflection failure", e);
+ }
+ }
}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/StandardNames.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/StandardNames.java
index 2c59d82..6d28950 100644
--- a/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/StandardNames.java
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/StandardNames.java
@@ -153,17 +153,26 @@
provideCipherPaddings("AES", new String[] {"PKCS7Padding"});
}
- provideSslContextEnabledProtocols("TLS", TLSVersion.TLSv1, TLSVersion.TLSv13);
- provideSslContextEnabledProtocols("TLSv1", TLSVersion.TLSv1, TLSVersion.TLSv12);
- provideSslContextEnabledProtocols("TLSv1.1", TLSVersion.TLSv1, TLSVersion.TLSv12);
- provideSslContextEnabledProtocols("TLSv1.2", TLSVersion.TLSv1, TLSVersion.TLSv12);
- provideSslContextEnabledProtocols("TLSv1.3", TLSVersion.TLSv1, TLSVersion.TLSv13);
- provideSslContextEnabledProtocols("Default", TLSVersion.TLSv1, TLSVersion.TLSv13);
+ if (TestUtils.isTlsV1Supported()) {
+ provideSslContextEnabledProtocols("TLS", TLSVersion.TLSv1, TLSVersion.TLSv13);
+ provideSslContextEnabledProtocols("TLSv1", TLSVersion.TLSv1, TLSVersion.TLSv12);
+ provideSslContextEnabledProtocols("TLSv1.1", TLSVersion.TLSv1, TLSVersion.TLSv12);
+ provideSslContextEnabledProtocols("TLSv1.2", TLSVersion.TLSv1, TLSVersion.TLSv12);
+ provideSslContextEnabledProtocols("TLSv1.3", TLSVersion.TLSv1, TLSVersion.TLSv13);
+ provideSslContextEnabledProtocols("Default", TLSVersion.TLSv1, TLSVersion.TLSv13);
+ } else {
+ provideSslContextEnabledProtocols("TLS", TLSVersion.TLSv12, TLSVersion.TLSv13);
+ provideSslContextEnabledProtocols("TLSv1.2", TLSVersion.TLSv12, TLSVersion.TLSv12);
+ provideSslContextEnabledProtocols("TLSv1.3", TLSVersion.TLSv12, TLSVersion.TLSv13);
+ provideSslContextEnabledProtocols("Default", TLSVersion.TLSv12, TLSVersion.TLSv13);
+ }
}
public static final String SSL_CONTEXT_PROTOCOLS_DEFAULT = "Default";
+ public static final Set<String> SSL_CONTEXT_PROTOCOLS_ALL =
+ new HashSet<String>(Arrays.asList("TLS", "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"));
public static final Set<String> SSL_CONTEXT_PROTOCOLS = new HashSet<String>(
- Arrays.asList(SSL_CONTEXT_PROTOCOLS_DEFAULT, "TLS", "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"));
+ Arrays.asList(SSL_CONTEXT_PROTOCOLS_DEFAULT, "TLS", "TLSv1.2", "TLSv1.3"));
public static final Set<String> SSL_CONTEXT_PROTOCOLS_WITH_DEFAULT_CONFIG = new HashSet<String>(
Arrays.asList(SSL_CONTEXT_PROTOCOLS_DEFAULT, "TLS", "TLSv1.3"));
// Deprecated TLS protocols... May or may not be present or enabled.
@@ -185,8 +194,15 @@
}
}
- public static final Set<String> SSL_SOCKET_PROTOCOLS =
- new HashSet<String>(Arrays.asList("TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"));
+ public static final Set<String> SSL_SOCKET_PROTOCOLS = new HashSet<>();
+ static {
+ SSL_SOCKET_PROTOCOLS.add("TLSv1.2");
+ SSL_SOCKET_PROTOCOLS.add("TLSv1.3");
+ if (TestUtils.isTlsV1Supported()) {
+ SSL_SOCKET_PROTOCOLS.add("TLSv1");
+ SSL_SOCKET_PROTOCOLS.add("TLSv1.1");
+ }
+ }
private enum TLSVersion {
SSLv3("SSLv3"),
diff --git a/repackaged/testing/src/main/java/tests/util/ServiceTester.java b/repackaged/testing/src/main/java/tests/util/ServiceTester.java
index f5298b7..5d3c37e 100644
--- a/repackaged/testing/src/main/java/tests/util/ServiceTester.java
+++ b/repackaged/testing/src/main/java/tests/util/ServiceTester.java
@@ -194,9 +194,9 @@
try {
test.test(p, algorithm);
} catch (Exception | AssertionError e) {
- errors.append("Failure testing " + service + ":" + algorithm + " from provider " + p.getName()
- + ":\n");
- e.printStackTrace(errors);
+ errors.append("Failure testing " + service + ":" + algorithm + " from provider "
+ + p.getName() + ":\n");
+ e.printStackTrace(errors);
}
}
diff --git a/testing/src/main/java/org/conscrypt/ChannelType.java b/testing/src/main/java/org/conscrypt/ChannelType.java
index 09dd582..23e09a0 100644
--- a/testing/src/main/java/org/conscrypt/ChannelType.java
+++ b/testing/src/main/java/org/conscrypt/ChannelType.java
@@ -38,24 +38,24 @@
public enum ChannelType {
NONE {
@Override
- SSLSocket newClientSocket(SSLSocketFactory factory, InetAddress address, int port)
+ public SSLSocket newClientSocket(SSLSocketFactory factory, InetAddress address, int port)
throws IOException {
return clientMode(factory.createSocket(address, port));
}
@Override
- ServerSocket newServerSocket(SSLServerSocketFactory factory) throws IOException {
+ public ServerSocket newServerSocket(SSLServerSocketFactory factory) throws IOException {
return factory.createServerSocket(0, 50, InetAddress.getLoopbackAddress());
}
@Override
- SSLSocket accept(ServerSocket socket, SSLSocketFactory unused) throws IOException {
+ public SSLSocket accept(ServerSocket socket, SSLSocketFactory unused) throws IOException {
return serverMode(socket.accept());
}
},
NO_CHANNEL {
@Override
- SSLSocket newClientSocket(SSLSocketFactory factory, InetAddress address, int port)
+ public SSLSocket newClientSocket(SSLSocketFactory factory, InetAddress address, int port)
throws IOException {
Socket wrapped = new Socket(address, port);
assertNull(wrapped.getChannel());
@@ -64,13 +64,13 @@
}
@Override
- ServerSocket newServerSocket(SSLServerSocketFactory unused) throws IOException {
+ public ServerSocket newServerSocket(SSLServerSocketFactory unused) throws IOException {
return ServerSocketFactory.getDefault().createServerSocket(
0, 50, InetAddress.getLoopbackAddress());
}
@Override
- SSLSocket accept(ServerSocket serverSocket, SSLSocketFactory factory) throws IOException {
+ public SSLSocket accept(ServerSocket serverSocket, SSLSocketFactory factory) throws IOException {
assertFalse(serverSocket instanceof SSLServerSocket);
Socket wrapped = serverSocket.accept();
assertNull(wrapped.getChannel());
@@ -81,21 +81,21 @@
},
CHANNEL {
@Override
- SSLSocket newClientSocket(SSLSocketFactory factory, InetAddress address, int port)
+ public SSLSocket newClientSocket(SSLSocketFactory factory, InetAddress address, int port)
throws IOException {
Socket wrapped = SocketChannel.open(new InetSocketAddress(address, port)).socket();
return clientMode(factory.createSocket(wrapped, address.getHostName(), port, true));
}
@Override
- ServerSocket newServerSocket(SSLServerSocketFactory unused) throws IOException {
+ public ServerSocket newServerSocket(SSLServerSocketFactory unused) throws IOException {
return ServerSocketChannel.open()
.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0))
.socket();
}
@Override
- SSLSocket accept(ServerSocket serverSocket, SSLSocketFactory factory) throws IOException {
+ public SSLSocket accept(ServerSocket serverSocket, SSLSocketFactory factory) throws IOException {
assertFalse(serverSocket instanceof SSLServerSocket);
ServerSocketChannel serverChannel = serverSocket.getChannel();
@@ -111,10 +111,10 @@
}
};
- abstract SSLSocket newClientSocket(SSLSocketFactory factory, InetAddress address, int port)
+ public abstract SSLSocket newClientSocket(SSLSocketFactory factory, InetAddress address, int port)
throws IOException;
- abstract ServerSocket newServerSocket(SSLServerSocketFactory factory) throws IOException;
- abstract SSLSocket accept(ServerSocket socket, SSLSocketFactory factory) throws IOException;
+ public abstract ServerSocket newServerSocket(SSLServerSocketFactory factory) throws IOException;
+ public abstract SSLSocket accept(ServerSocket socket, SSLSocketFactory factory) throws IOException;
private static SSLSocket clientMode(Socket socket) {
SSLSocket sslSocket = (SSLSocket) socket;
diff --git a/testing/src/main/java/org/conscrypt/TestUtils.java b/testing/src/main/java/org/conscrypt/TestUtils.java
index 92bce9e..e5daa80 100644
--- a/testing/src/main/java/org/conscrypt/TestUtils.java
+++ b/testing/src/main/java/org/conscrypt/TestUtils.java
@@ -319,7 +319,7 @@
}
}
- static SSLSocketFactory setUseEngineSocket(
+ public static SSLSocketFactory setUseEngineSocket(
SSLSocketFactory conscryptFactory, boolean useEngineSocket) {
try {
Class<?> clazz = conscryptClass("Conscrypt");
@@ -332,7 +332,7 @@
}
}
- static SSLServerSocketFactory setUseEngineSocket(
+ public static SSLServerSocketFactory setUseEngineSocket(
SSLServerSocketFactory conscryptFactory, boolean useEngineSocket) {
try {
Class<?> clazz = conscryptClass("Conscrypt");
@@ -472,12 +472,12 @@
return msg;
}
- static SSLContext newClientSslContext(Provider provider) {
+ public static SSLContext newClientSslContext(Provider provider) {
SSLContext context = newContext(provider);
return initClientSslContext(context);
}
- static SSLContext newServerSslContext(Provider provider) {
+ public static SSLContext newServerSslContext(Provider provider) {
SSLContext context = newContext(provider);
return initServerSslContext(context);
}
@@ -833,4 +833,32 @@
throw new IllegalStateException("Reflection failure", e);
}
}
+
+ // Find base method via reflection due to possible version skew on Android
+ // and visibility issues when building with Gradle.
+ public static boolean isTlsV1Supported() {
+ try {
+ return (Boolean) conscryptClass("Platform")
+ .getDeclaredMethod("isTlsV1Supported")
+ .invoke(null);
+ } catch (NoSuchMethodException e) {
+ return true;
+ } catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException e) {
+ throw new IllegalStateException("Reflection failure", e);
+ }
+ }
+
+ // Find base method via reflection due to possible version skew on Android
+ // and visibility issues when building with Gradle.
+ public static boolean isTlsV1Filtered() {
+ try {
+ return (Boolean) conscryptClass("Platform")
+ .getDeclaredMethod("isTlsV1Filtered")
+ .invoke(null);
+ } catch (NoSuchMethodException e) {
+ return true;
+ } catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException e) {
+ throw new IllegalStateException("Reflection failure", e);
+ }
+ }
}
diff --git a/testing/src/main/java/org/conscrypt/java/security/StandardNames.java b/testing/src/main/java/org/conscrypt/java/security/StandardNames.java
index 54a26d0..4c480ec 100644
--- a/testing/src/main/java/org/conscrypt/java/security/StandardNames.java
+++ b/testing/src/main/java/org/conscrypt/java/security/StandardNames.java
@@ -152,17 +152,26 @@
provideCipherPaddings("AES", new String[] {"PKCS7Padding"});
}
- provideSslContextEnabledProtocols("TLS", TLSVersion.TLSv1, TLSVersion.TLSv13);
- provideSslContextEnabledProtocols("TLSv1", TLSVersion.TLSv1, TLSVersion.TLSv12);
- provideSslContextEnabledProtocols("TLSv1.1", TLSVersion.TLSv1, TLSVersion.TLSv12);
- provideSslContextEnabledProtocols("TLSv1.2", TLSVersion.TLSv1, TLSVersion.TLSv12);
- provideSslContextEnabledProtocols("TLSv1.3", TLSVersion.TLSv1, TLSVersion.TLSv13);
- provideSslContextEnabledProtocols("Default", TLSVersion.TLSv1, TLSVersion.TLSv13);
+ if (TestUtils.isTlsV1Supported()) {
+ provideSslContextEnabledProtocols("TLS", TLSVersion.TLSv1, TLSVersion.TLSv13);
+ provideSslContextEnabledProtocols("TLSv1", TLSVersion.TLSv1, TLSVersion.TLSv12);
+ provideSslContextEnabledProtocols("TLSv1.1", TLSVersion.TLSv1, TLSVersion.TLSv12);
+ provideSslContextEnabledProtocols("TLSv1.2", TLSVersion.TLSv1, TLSVersion.TLSv12);
+ provideSslContextEnabledProtocols("TLSv1.3", TLSVersion.TLSv1, TLSVersion.TLSv13);
+ provideSslContextEnabledProtocols("Default", TLSVersion.TLSv1, TLSVersion.TLSv13);
+ } else {
+ provideSslContextEnabledProtocols("TLS", TLSVersion.TLSv12, TLSVersion.TLSv13);
+ provideSslContextEnabledProtocols("TLSv1.2", TLSVersion.TLSv12, TLSVersion.TLSv12);
+ provideSslContextEnabledProtocols("TLSv1.3", TLSVersion.TLSv12, TLSVersion.TLSv13);
+ provideSslContextEnabledProtocols("Default", TLSVersion.TLSv12, TLSVersion.TLSv13);
+ }
}
public static final String SSL_CONTEXT_PROTOCOLS_DEFAULT = "Default";
+ public static final Set<String> SSL_CONTEXT_PROTOCOLS_ALL =
+ new HashSet<String>(Arrays.asList("TLS", "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"));
public static final Set<String> SSL_CONTEXT_PROTOCOLS = new HashSet<String>(
- Arrays.asList(SSL_CONTEXT_PROTOCOLS_DEFAULT, "TLS", "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"));
+ Arrays.asList(SSL_CONTEXT_PROTOCOLS_DEFAULT, "TLS", "TLSv1.2", "TLSv1.3"));
public static final Set<String> SSL_CONTEXT_PROTOCOLS_WITH_DEFAULT_CONFIG = new HashSet<String>(
Arrays.asList(SSL_CONTEXT_PROTOCOLS_DEFAULT, "TLS", "TLSv1.3"));
// Deprecated TLS protocols... May or may not be present or enabled.
@@ -184,8 +193,15 @@
}
}
- public static final Set<String> SSL_SOCKET_PROTOCOLS =
- new HashSet<String>(Arrays.asList("TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"));
+ public static final Set<String> SSL_SOCKET_PROTOCOLS = new HashSet<>();
+ static {
+ SSL_SOCKET_PROTOCOLS.add("TLSv1.2");
+ SSL_SOCKET_PROTOCOLS.add("TLSv1.3");
+ if (TestUtils.isTlsV1Supported()) {
+ SSL_SOCKET_PROTOCOLS.add("TLSv1");
+ SSL_SOCKET_PROTOCOLS.add("TLSv1.1");
+ }
+ }
private enum TLSVersion {
SSLv3("SSLv3"),