Cert issues with Android Studio / Gradle

Hello, going absolutely crazy here trying to get Gradle within Android Studio working within a corporate environment using an SSL Proxy!

Error:

Caused by: org.gradle.internal.resource.transport.http.HttpRequestException: The server may not support the client's requested TLS protocol versions: (TLSv1.2, TLSv1.3). You may need to configure the client to allow other protocols to be used. For more on this, please refer to
https://docs.gradle.org/8.2/userguide/build_environment.html#sec:gradle_system_properties
in the Gradle documentation.
	at org.gradle.internal.resource.transport.http.HttpClientHelper.createCause(HttpClientHelper.java:134)
	... 60 more
Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

This is what I have done so far:

  • Verified the install location of Java being used by Gradle within AS
  • Installed the corporate certs (we have 1 Root, 1 Intermediate, and 2 other certs, 1 is EC 1 is not) as chains in the Java store. This has fixed Java issues with other applications but not this.
  • Added the certs within Android Studio, also allowed untrusted certs
  • Invalidated cache

Really not sure where to go next :frowning:

Thanks!

Did you configure the required proxy as documented at Build Environment?

“unable to find valid certification path to requested target” when proxies are involved often mean that some “you need to use a proxy” page is returned when not using the proxy which then does not have an SSL certificate matching the requested domain.

You can also debug the SSL handshake by enabling java.net.debug messages, but it often needs a bit of experience to interpret this logging accordingly.

So the proxy is inline/silent/invisible, so there’s no need to manually configure it.

Within Android Studio, how does one enable those debugs? Thanks!

As it is while running Gradle, it should not be AS-specific.
Maybe start with getting the Gradle build running from commandline to rule out any AS involvement.
To get that logging from Gradle runs, for example add systemProp.javax.net.debug = all or any other valid value for javax.net.debug to your <GRADLE_USER_HOME>/gradle.properties or <root project dir>/gradle.properties file (create it if it does not exist).

Thanks, I will ask the user to try this. Do you know the command from executing directly from the CLI?

./gradlew whateverTaskYouWantToRun

So since yesterday (before changing anything), the error has changed slightly but still cert related:

Facing this error after performing the steps which you have suggested : 
2: Task failed with an exception.
-----------
* What went wrong:
Execution failed for task ':app:processPartnerReleaseVersionCodes'.
> A failure occurred while executing com.github.triplet.gradle.play.tasks.ProcessArtifactVersionCodes$VersionCoder
   > Error getting access token for service account: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target, iss: id-seal@api-6796791038823196390-309564.iam.gserviceaccount.com

Added this line to gradle.properties at the bottom:

systemProp.javax.net.debug=all

# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
android.useDeprecatedNdk=true
org.gradle.jvmargs=-Xmx5120M
android.useAndroidX=true
android.enableJetifier=true
android.jetifier.ignorelist=bcprov-jdk15on
android.defaults.buildfeatures.buildconfig=true
android.nonTransitiveRClass=false
android.nonFinalResIds=false
systemProp.javax.net.debug=all

Just wondering where do these debugs go? The error was exactly the same from the CLI.

Thanks!

They go directly to stderr, so you should see those logs directly in the output when invoking the build and with all they are quite verbose so you should usually not miss them.

So I see it making POSTS to https://oauth2.googleapis.com/token, but when I browse to that URL, says it doesn’t exist?

The certs being presented appear to be the ones I have already added to the Java keystore. Is there a way from the CLI to verify which keystore is being used?

Thanks!

but when I browse to that URL, says it doesn’t exist?

If you GET the URL you get 404.
If you POST to that URL it “works”.

The certs being presented appear to be the ones I have already added to the Java keystore. Is there a way from the CLI to verify which keystore is being used?

Afair you should at least see the actual certificates in the debug output, but the kestore I don’t think so.

I guess there must be a config file somewhere for Gradle to point to a specific Java installation?

There are multiple Java processes involved and each can theoretically have a different Java version.
If the problem happens with something in the daemon and you did not configure an explicit JDK via Gradle properties, it should use the same that is used to start the Gradle CLI, which is what is configured via JAVA_HOME or if absent the java found in the PATH.

You could also check with a process manager which Java is used.

So I downloaded a utility from Atlassian called “SSL Poke”, and this confirmed no SSL issues using the running Java version to oauth2.googleapis.com

When he’s running from the command line, he is in fact launching this file: build_apk.sh.

I am wondering how this all ties in. He also now only has 1 Java instance installed.

build_apk:

#!/bin/bash

echo "Welcome, Initiating build"

java17

fastlane cleanTask

echo "--------------------------------------------------"
echo "Some keypair strings with numbers redacted: 9001234"
echo "--------------------------------------------------"

echo "enter RTN number: "
read -r rtn
echo "select build environment"
select env in qa-mobile staging production dev1 dev2 dev3 dev4 dev5 dev6 dev7 dev-infra
do
echo "selected environment: $env"
break
done

branch=$(git symbolic-ref --short HEAD)

echo "select build type"
select buildType in debug release appetize veracode
do
echo "selected Build Type: $buildType"
break
done

echo "build only or fetch assets and build"
select buildOnly in buildOnly fetchAndBuild
do
if [ $buildOnly == "buildOnly" ];
then
    fastlane generateBuild rtn:"$rtn" branch:"$branch" buildEnv:$env buildType:$buildType
    break
else
   fastlane fetchAssets rtn:"$rtn" branch:"$branch" buildEnv:$env buildType:$buildType
   fastlane generateBuild rtn:"$rtn" branch:"$branch" buildEnv:$env buildType:$buildType
   break
fi
done


Also, is there a way to confirm which Java keystore is being used in this process?