Skip to content

Commit c7cc4f8

Browse files
authored
[ok_http] Add support for client certificates using Java PrivateKeys (#1444)
1 parent 6d99ff5 commit c7cc4f8

File tree

23 files changed

+29094
-7011
lines changed

23 files changed

+29094
-7011
lines changed

.github/workflows/okhttp.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
- uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b
3333
with:
3434
distribution: 'zulu'
35-
java-version: '17'
35+
java-version: '21'
3636
- uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1
3737
with:
3838
channel: 'stable'
@@ -50,7 +50,7 @@ jobs:
5050
if: always() && steps.install.outcome == 'success'
5151
with:
5252
# api-level/minSdkVersion should be help in sync in:
53-
# - .github/workflows/ok.yml
53+
# - .github/workflows/okhttp.yml
5454
# - pkgs/ok_http/android/build.gradle
5555
# - pkgs/ok_http/example/android/app/build.gradle
5656
api-level: 21

pkgs/cronet_http/android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ buildscript {
99
}
1010

1111
dependencies {
12-
classpath 'com.android.tools.build:gradle:8.1.0'
12+
classpath 'com.android.tools.build:gradle:8.9.0'
1313
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
1414
}
1515
}

pkgs/flutter_http_example/android/gradle/wrapper/gradle-wrapper.properties

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
4+
networkTimeout=10000
5+
validateDistributionUrl=true
36
zipStoreBase=GRADLE_USER_HOME
47
zipStorePath=wrapper/dists
5-
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip

pkgs/http_client_conformance_tests/lib/src/response_headers_tests.dart

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,8 @@ void testResponseHeaders(Client client,
163163
response.headers['foo'],
164164
anyOf(
165165
'1 2', // RFC-specified behavior
166-
'1' // Common client behavior.
167-
));
166+
// Common client behavior (Cronet, Apple URL Loading System).
167+
'1'));
168168
} on ClientException {
169169
// The client rejected the response, which is allowed per RFC-9110.
170170
}
@@ -178,9 +178,11 @@ void testResponseHeaders(Client client,
178178
expect(
179179
response.headers['foo'],
180180
anyOf(
181-
'1 2', // RFC-specified behavior
182-
'1' // Common client behavior.
183-
));
181+
'1 2', // RFC-specified behavior
182+
// Common client behavior (Cronet, Apple URL Loading System).
183+
'1',
184+
'1\r2', // Common client behavior (Java).
185+
));
184186
} on ClientException {
185187
// The client rejected the response, which is allowed per RFC-9110.
186188
}

pkgs/ok_http/CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
- `OkHttpClient` now receives an `OkHttpClientConfiguration` to configure the client on a per-call basis.
44
- `OkHttpClient` supports setting four types of timeouts: [`connectTimeout`](https://square.github.io/okhttp/5.x/okhttp/okhttp3/-ok-http-client/-builder/connect-timeout.html), [`readTimeout`](https://square.github.io/okhttp/5.x/okhttp/okhttp3/-ok-http-client/-builder/read-timeout.html), [`writeTimeout`](https://square.github.io/okhttp/5.x/okhttp/okhttp3/-ok-http-client/-builder/write-timeout.html), and [`callTimeout`](https://square.github.io/okhttp/5.x/okhttp/okhttp3/-ok-http-client/-builder/call-timeout.html), using the `OkHttpClientConfiguration`.
5-
- Update to `jnigen` 0.12.2
5+
- Upgrade to `jni` 0.13.0
6+
- Upgrade to `jnigen` 0.13.1
7+
- `OKHttpClient` supports client certificates.
68

79
## 0.1.0
810

pkgs/ok_http/android/build.gradle

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,15 @@ group = "com.example.ok_http"
44
version = "1.0"
55

66
buildscript {
7-
// Required to support `okhttp:4.12.0`.
8-
ext.kotlin_version = '1.9.23'
7+
ext.kotlin_version = '2.1.10'
98
repositories {
109
google()
1110
mavenCentral()
1211
}
1312

1413
dependencies {
1514
// The Android Gradle Plugin knows how to build native code with the NDK.
16-
classpath("com.android.tools.build:gradle:7.3.0")
15+
classpath("com.android.tools.build:gradle:8.1.2")
1716
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
1817
}
1918
}
@@ -34,7 +33,7 @@ android {
3433
}
3534

3635
kotlinOptions {
37-
jvmTarget = '1.8'
36+
jvmTarget = JavaVersion.VERSION_21
3837
}
3938

4039
sourceSets {
@@ -52,8 +51,8 @@ android {
5251
ndkVersion = android.ndkVersion
5352

5453
compileOptions {
55-
sourceCompatibility = JavaVersion.VERSION_1_8
56-
targetCompatibility = JavaVersion.VERSION_1_8
54+
sourceCompatibility = JavaVersion.VERSION_21
55+
targetCompatibility = JavaVersion.VERSION_21
5756
}
5857

5958
defaultConfig {
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
package com.example.ok_http
6+
7+
import java.net.Socket
8+
import java.security.Principal
9+
import java.security.PrivateKey
10+
import java.security.cert.X509Certificate
11+
import javax.net.ssl.SSLEngine
12+
import javax.net.ssl.X509ExtendedKeyManager
13+
14+
/**
15+
* A `X509ExtendedKeyManager` that always responds with the configured
16+
* private key, certificate chain, and alias.
17+
*/
18+
class FixedResponseX509ExtendedKeyManager(
19+
private val certificateChain: Array<X509Certificate>,
20+
private val privateKey: PrivateKey,
21+
private val alias: String,
22+
) : X509ExtendedKeyManager() {
23+
24+
override fun getClientAliases(keyType: String, issuers: Array<Principal>?) = arrayOf(alias)
25+
26+
override fun chooseClientAlias(
27+
keyType: Array<String>,
28+
issuers: Array<Principal>?,
29+
socket: Socket?,
30+
) = alias
31+
32+
override fun getServerAliases(keyType: String, issuers: Array<Principal>?) = arrayOf(alias)
33+
34+
override fun chooseServerAlias(
35+
keyType: String,
36+
issuers: Array<Principal>?,
37+
socket: Socket?,
38+
) = alias
39+
40+
override fun getCertificateChain(alias: String) = certificateChain
41+
42+
override fun getPrivateKey(alias: String) = privateKey
43+
44+
override fun chooseEngineClientAlias(
45+
keyType: Array<String?>?,
46+
issuers: Array<Principal?>?,
47+
engine: SSLEngine?,
48+
) = alias
49+
50+
override fun chooseEngineServerAlias(
51+
keyType: String?,
52+
issuers: Array<Principal?>?,
53+
engine: SSLEngine?
54+
) = alias
55+
}

pkgs/ok_http/example/android/app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ android {
2929
ndkVersion = flutter.ndkVersion
3030

3131
compileOptions {
32-
sourceCompatibility = JavaVersion.VERSION_1_8
33-
targetCompatibility = JavaVersion.VERSION_1_8
32+
sourceCompatibility = JavaVersion.VERSION_21
33+
targetCompatibility = JavaVersion.VERSION_21
3434
}
3535

3636
defaultConfig {

pkgs/ok_http/example/android/gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
33
zipStoreBase=GRADLE_USER_HOME
44
zipStorePath=wrapper/dists
5-
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip
5+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip

pkgs/ok_http/example/android/settings.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pluginManagement {
1818

1919
plugins {
2020
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
21-
id "com.android.application" version "7.3.0" apply false
21+
id "com.android.application" version "8.2.1" apply false
2222
id "org.jetbrains.kotlin.android" version "1.9.23" apply false
2323
}
2424

0 commit comments

Comments
 (0)