1*3c7ae9deSAndroid Build Coastguard Worker /**
2*3c7ae9deSAndroid Build Coastguard Worker * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3*3c7ae9deSAndroid Build Coastguard Worker * SPDX-License-Identifier: Apache-2.0.
4*3c7ae9deSAndroid Build Coastguard Worker */
5*3c7ae9deSAndroid Build Coastguard Worker
6*3c7ae9deSAndroid Build Coastguard Worker #include <jni.h>
7*3c7ae9deSAndroid Build Coastguard Worker
8*3c7ae9deSAndroid Build Coastguard Worker #include <aws/common/string.h>
9*3c7ae9deSAndroid Build Coastguard Worker #include <aws/io/tls_channel_handler.h>
10*3c7ae9deSAndroid Build Coastguard Worker
11*3c7ae9deSAndroid Build Coastguard Worker #include "crt.h"
12*3c7ae9deSAndroid Build Coastguard Worker #include "java_class_ids.h"
13*3c7ae9deSAndroid Build Coastguard Worker #include "tls_context_pkcs11_options.h"
14*3c7ae9deSAndroid Build Coastguard Worker
15*3c7ae9deSAndroid Build Coastguard Worker #include "custom_key_op_handler.h"
16*3c7ae9deSAndroid Build Coastguard Worker
17*3c7ae9deSAndroid Build Coastguard Worker /* Have to wrap the native struct so we can manage string lifetime */
18*3c7ae9deSAndroid Build Coastguard Worker struct jni_tls_ctx_options {
19*3c7ae9deSAndroid Build Coastguard Worker /* Must be first thing in the structure so casts to aws_tls_ctx_options work */
20*3c7ae9deSAndroid Build Coastguard Worker struct aws_tls_ctx_options options;
21*3c7ae9deSAndroid Build Coastguard Worker /* these strings get copied from java, so we don't have to pin and track references */
22*3c7ae9deSAndroid Build Coastguard Worker struct aws_string *ca_file;
23*3c7ae9deSAndroid Build Coastguard Worker struct aws_string *ca_path;
24*3c7ae9deSAndroid Build Coastguard Worker struct aws_string *alpn_list;
25*3c7ae9deSAndroid Build Coastguard Worker struct aws_string *certificate_path;
26*3c7ae9deSAndroid Build Coastguard Worker struct aws_string *private_key_path;
27*3c7ae9deSAndroid Build Coastguard Worker struct aws_string *pkcs12_path;
28*3c7ae9deSAndroid Build Coastguard Worker struct aws_string *pkcs12_password;
29*3c7ae9deSAndroid Build Coastguard Worker struct aws_string *certificate;
30*3c7ae9deSAndroid Build Coastguard Worker struct aws_string *private_key;
31*3c7ae9deSAndroid Build Coastguard Worker struct aws_string *windows_cert_store_path;
32*3c7ae9deSAndroid Build Coastguard Worker struct aws_string *ca_root;
33*3c7ae9deSAndroid Build Coastguard Worker
34*3c7ae9deSAndroid Build Coastguard Worker struct aws_tls_ctx_pkcs11_options *pkcs11_options;
35*3c7ae9deSAndroid Build Coastguard Worker
36*3c7ae9deSAndroid Build Coastguard Worker struct aws_custom_key_op_handler *custom_key_op_handler;
37*3c7ae9deSAndroid Build Coastguard Worker };
38*3c7ae9deSAndroid Build Coastguard Worker
39*3c7ae9deSAndroid Build Coastguard Worker /* on 32-bit platforms, casting pointers to longs throws a warning we don't need */
40*3c7ae9deSAndroid Build Coastguard Worker #if UINTPTR_MAX == 0xffffffff
41*3c7ae9deSAndroid Build Coastguard Worker # if defined(_MSC_VER)
42*3c7ae9deSAndroid Build Coastguard Worker # pragma warning(push)
43*3c7ae9deSAndroid Build Coastguard Worker # pragma warning(disable : 4305) /* 'type cast': truncation from 'jlong' to 'jni_tls_ctx_options *' */
44*3c7ae9deSAndroid Build Coastguard Worker # else
45*3c7ae9deSAndroid Build Coastguard Worker # pragma GCC diagnostic push
46*3c7ae9deSAndroid Build Coastguard Worker # pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
47*3c7ae9deSAndroid Build Coastguard Worker # pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
48*3c7ae9deSAndroid Build Coastguard Worker # endif
49*3c7ae9deSAndroid Build Coastguard Worker #endif
50*3c7ae9deSAndroid Build Coastguard Worker
s_jni_tls_ctx_options_destroy(struct jni_tls_ctx_options * tls)51*3c7ae9deSAndroid Build Coastguard Worker static void s_jni_tls_ctx_options_destroy(struct jni_tls_ctx_options *tls) {
52*3c7ae9deSAndroid Build Coastguard Worker if (tls == NULL) {
53*3c7ae9deSAndroid Build Coastguard Worker return;
54*3c7ae9deSAndroid Build Coastguard Worker }
55*3c7ae9deSAndroid Build Coastguard Worker
56*3c7ae9deSAndroid Build Coastguard Worker aws_string_destroy(tls->ca_file);
57*3c7ae9deSAndroid Build Coastguard Worker aws_string_destroy(tls->ca_path);
58*3c7ae9deSAndroid Build Coastguard Worker aws_string_destroy(tls->alpn_list);
59*3c7ae9deSAndroid Build Coastguard Worker aws_string_destroy(tls->certificate_path);
60*3c7ae9deSAndroid Build Coastguard Worker aws_string_destroy(tls->private_key_path);
61*3c7ae9deSAndroid Build Coastguard Worker aws_string_destroy(tls->pkcs12_path);
62*3c7ae9deSAndroid Build Coastguard Worker aws_string_destroy_secure(tls->pkcs12_password);
63*3c7ae9deSAndroid Build Coastguard Worker aws_string_destroy(tls->certificate);
64*3c7ae9deSAndroid Build Coastguard Worker aws_string_destroy_secure(tls->private_key);
65*3c7ae9deSAndroid Build Coastguard Worker aws_string_destroy(tls->windows_cert_store_path);
66*3c7ae9deSAndroid Build Coastguard Worker aws_string_destroy(tls->ca_root);
67*3c7ae9deSAndroid Build Coastguard Worker
68*3c7ae9deSAndroid Build Coastguard Worker aws_tls_ctx_pkcs11_options_from_java_destroy(tls->pkcs11_options);
69*3c7ae9deSAndroid Build Coastguard Worker aws_custom_key_op_handler_java_release(tls->custom_key_op_handler);
70*3c7ae9deSAndroid Build Coastguard Worker aws_tls_ctx_options_clean_up(&tls->options);
71*3c7ae9deSAndroid Build Coastguard Worker
72*3c7ae9deSAndroid Build Coastguard Worker struct aws_allocator *allocator = aws_jni_get_allocator();
73*3c7ae9deSAndroid Build Coastguard Worker aws_mem_release(allocator, tls);
74*3c7ae9deSAndroid Build Coastguard Worker }
75*3c7ae9deSAndroid Build Coastguard Worker
76*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT
Java_software_amazon_awssdk_crt_io_TlsContextOptions_tlsContextOptionsNew(JNIEnv * env,jclass jni_class,jint jni_min_tls_version,jint jni_cipher_pref,jstring jni_alpn,jstring jni_certificate,jstring jni_private_key,jstring jni_cert_path,jstring jni_key_path,jstring jni_ca,jstring jni_ca_filepath,jstring jni_ca_dirpath,jboolean jni_verify_peer,jstring jni_pkcs12_path,jstring jni_pkcs12_password,jobject jni_pkcs11_options,jobject jni_custom_key_op,jstring jni_windows_cert_store_path)77*3c7ae9deSAndroid Build Coastguard Worker jlong JNICALL Java_software_amazon_awssdk_crt_io_TlsContextOptions_tlsContextOptionsNew(
78*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
79*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
80*3c7ae9deSAndroid Build Coastguard Worker jint jni_min_tls_version,
81*3c7ae9deSAndroid Build Coastguard Worker jint jni_cipher_pref,
82*3c7ae9deSAndroid Build Coastguard Worker jstring jni_alpn,
83*3c7ae9deSAndroid Build Coastguard Worker jstring jni_certificate,
84*3c7ae9deSAndroid Build Coastguard Worker jstring jni_private_key,
85*3c7ae9deSAndroid Build Coastguard Worker jstring jni_cert_path,
86*3c7ae9deSAndroid Build Coastguard Worker jstring jni_key_path,
87*3c7ae9deSAndroid Build Coastguard Worker jstring jni_ca,
88*3c7ae9deSAndroid Build Coastguard Worker jstring jni_ca_filepath,
89*3c7ae9deSAndroid Build Coastguard Worker jstring jni_ca_dirpath,
90*3c7ae9deSAndroid Build Coastguard Worker jboolean jni_verify_peer,
91*3c7ae9deSAndroid Build Coastguard Worker jstring jni_pkcs12_path,
92*3c7ae9deSAndroid Build Coastguard Worker jstring jni_pkcs12_password,
93*3c7ae9deSAndroid Build Coastguard Worker jobject jni_pkcs11_options,
94*3c7ae9deSAndroid Build Coastguard Worker jobject jni_custom_key_op,
95*3c7ae9deSAndroid Build Coastguard Worker jstring jni_windows_cert_store_path) {
96*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
97*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
98*3c7ae9deSAndroid Build Coastguard Worker
99*3c7ae9deSAndroid Build Coastguard Worker struct aws_allocator *allocator = aws_jni_get_allocator();
100*3c7ae9deSAndroid Build Coastguard Worker struct jni_tls_ctx_options *tls = aws_mem_calloc(allocator, 1, sizeof(struct jni_tls_ctx_options));
101*3c7ae9deSAndroid Build Coastguard Worker AWS_FATAL_ASSERT(tls);
102*3c7ae9deSAndroid Build Coastguard Worker aws_tls_ctx_options_init_default_client(&tls->options, allocator);
103*3c7ae9deSAndroid Build Coastguard Worker
104*3c7ae9deSAndroid Build Coastguard Worker /* Certs or paths will cause an init, which overwrites other fields, so do those first */
105*3c7ae9deSAndroid Build Coastguard Worker if (jni_certificate && jni_private_key) {
106*3c7ae9deSAndroid Build Coastguard Worker tls->certificate = aws_jni_new_string_from_jstring(env, jni_certificate);
107*3c7ae9deSAndroid Build Coastguard Worker if (!tls->certificate) {
108*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "failed to get certificate string");
109*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
110*3c7ae9deSAndroid Build Coastguard Worker }
111*3c7ae9deSAndroid Build Coastguard Worker tls->private_key = aws_jni_new_string_from_jstring(env, jni_private_key);
112*3c7ae9deSAndroid Build Coastguard Worker if (!tls->private_key) {
113*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "failed to get privateKey string");
114*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
115*3c7ae9deSAndroid Build Coastguard Worker }
116*3c7ae9deSAndroid Build Coastguard Worker
117*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_cursor cert_cursor = aws_byte_cursor_from_string(tls->certificate);
118*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_cursor key_cursor = aws_byte_cursor_from_string(tls->private_key);
119*3c7ae9deSAndroid Build Coastguard Worker
120*3c7ae9deSAndroid Build Coastguard Worker if (aws_tls_ctx_options_init_client_mtls(&tls->options, allocator, &cert_cursor, &key_cursor)) {
121*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "aws_tls_ctx_options_init_client_mtls failed");
122*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
123*3c7ae9deSAndroid Build Coastguard Worker }
124*3c7ae9deSAndroid Build Coastguard Worker } else if (jni_cert_path && jni_key_path) {
125*3c7ae9deSAndroid Build Coastguard Worker tls->certificate_path = aws_jni_new_string_from_jstring(env, jni_cert_path);
126*3c7ae9deSAndroid Build Coastguard Worker if (!tls->certificate_path) {
127*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "failed to get certificatePath string");
128*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
129*3c7ae9deSAndroid Build Coastguard Worker }
130*3c7ae9deSAndroid Build Coastguard Worker tls->private_key_path = aws_jni_new_string_from_jstring(env, jni_key_path);
131*3c7ae9deSAndroid Build Coastguard Worker if (!tls->private_key_path) {
132*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "failed to get privateKeyPath string");
133*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
134*3c7ae9deSAndroid Build Coastguard Worker }
135*3c7ae9deSAndroid Build Coastguard Worker
136*3c7ae9deSAndroid Build Coastguard Worker if (aws_tls_ctx_options_init_client_mtls_from_path(
137*3c7ae9deSAndroid Build Coastguard Worker &tls->options,
138*3c7ae9deSAndroid Build Coastguard Worker allocator,
139*3c7ae9deSAndroid Build Coastguard Worker aws_string_c_str(tls->certificate_path),
140*3c7ae9deSAndroid Build Coastguard Worker aws_string_c_str(tls->private_key_path))) {
141*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "aws_tls_ctx_options_init_client_mtls_from_path failed");
142*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
143*3c7ae9deSAndroid Build Coastguard Worker }
144*3c7ae9deSAndroid Build Coastguard Worker } else if (jni_pkcs11_options) {
145*3c7ae9deSAndroid Build Coastguard Worker tls->pkcs11_options = aws_tls_ctx_pkcs11_options_from_java_new(env, jni_pkcs11_options);
146*3c7ae9deSAndroid Build Coastguard Worker if (tls->pkcs11_options == NULL) {
147*3c7ae9deSAndroid Build Coastguard Worker /* exception already thrown */
148*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
149*3c7ae9deSAndroid Build Coastguard Worker }
150*3c7ae9deSAndroid Build Coastguard Worker
151*3c7ae9deSAndroid Build Coastguard Worker if (aws_tls_ctx_options_init_client_mtls_with_pkcs11(&tls->options, allocator, tls->pkcs11_options)) {
152*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "aws_tls_ctx_options_init_client_mtls_with_pkcs11 failed");
153*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
154*3c7ae9deSAndroid Build Coastguard Worker }
155*3c7ae9deSAndroid Build Coastguard Worker } else if (jni_custom_key_op) {
156*3c7ae9deSAndroid Build Coastguard Worker
157*3c7ae9deSAndroid Build Coastguard Worker jobject jni_custom_key_op_handle = (*env)->GetObjectField(
158*3c7ae9deSAndroid Build Coastguard Worker env, jni_custom_key_op, tls_context_custom_key_operation_options_properties.operation_handler_field_id);
159*3c7ae9deSAndroid Build Coastguard Worker if (!jni_custom_key_op_handle) {
160*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(
161*3c7ae9deSAndroid Build Coastguard Worker env, "could not get custom operation handler from jni_custom_key_op_handle!");
162*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
163*3c7ae9deSAndroid Build Coastguard Worker }
164*3c7ae9deSAndroid Build Coastguard Worker
165*3c7ae9deSAndroid Build Coastguard Worker tls->custom_key_op_handler = aws_custom_key_op_handler_java_new(env, jni_custom_key_op_handle);
166*3c7ae9deSAndroid Build Coastguard Worker
167*3c7ae9deSAndroid Build Coastguard Worker /* Certificate needs to be set, but there are multiple ways to get it */
168*3c7ae9deSAndroid Build Coastguard Worker jstring jni_custom_key_op_cert_path = (*env)->GetObjectField(
169*3c7ae9deSAndroid Build Coastguard Worker env, jni_custom_key_op, tls_context_custom_key_operation_options_properties.certificate_file_path_field_id);
170*3c7ae9deSAndroid Build Coastguard Worker jstring jni_custom_key_op_cert_contents = (*env)->GetObjectField(
171*3c7ae9deSAndroid Build Coastguard Worker env,
172*3c7ae9deSAndroid Build Coastguard Worker jni_custom_key_op,
173*3c7ae9deSAndroid Build Coastguard Worker tls_context_custom_key_operation_options_properties.certificate_file_contents_field_id);
174*3c7ae9deSAndroid Build Coastguard Worker
175*3c7ae9deSAndroid Build Coastguard Worker if (jni_custom_key_op_cert_path && jni_custom_key_op_cert_contents) {
176*3c7ae9deSAndroid Build Coastguard Worker /* Cannot have both a certificate path and data - use one or the other */
177*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(
178*3c7ae9deSAndroid Build Coastguard Worker env, "Custom key operation handler: cannot have both certificate file path and certificate contents!");
179*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
180*3c7ae9deSAndroid Build Coastguard Worker } else if (jni_custom_key_op_cert_contents) {
181*3c7ae9deSAndroid Build Coastguard Worker /* If we have the certificate contents, then use it directly */
182*3c7ae9deSAndroid Build Coastguard Worker tls->certificate = aws_jni_new_string_from_jstring(env, jni_custom_key_op_cert_contents);
183*3c7ae9deSAndroid Build Coastguard Worker if (!tls->certificate) {
184*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(
185*3c7ae9deSAndroid Build Coastguard Worker env, "Custom key operation handler: failed to get certificate contents string");
186*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
187*3c7ae9deSAndroid Build Coastguard Worker }
188*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_cursor certificate_byte_cursor = aws_byte_cursor_from_string(tls->certificate);
189*3c7ae9deSAndroid Build Coastguard Worker
190*3c7ae9deSAndroid Build Coastguard Worker /* Initialize the client with a custom key operation */
191*3c7ae9deSAndroid Build Coastguard Worker if (aws_tls_ctx_options_init_client_mtls_with_custom_key_operations(
192*3c7ae9deSAndroid Build Coastguard Worker &tls->options, allocator, tls->custom_key_op_handler, &certificate_byte_cursor) != AWS_OP_SUCCESS) {
193*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(
194*3c7ae9deSAndroid Build Coastguard Worker env, "aws_tls_ctx_options_init_client_mtls_with_custom_key_operations failed");
195*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
196*3c7ae9deSAndroid Build Coastguard Worker }
197*3c7ae9deSAndroid Build Coastguard Worker } else if (jni_custom_key_op_cert_path) {
198*3c7ae9deSAndroid Build Coastguard Worker /* If we have a certificate path, we need to get the certificate data from it and use that */
199*3c7ae9deSAndroid Build Coastguard Worker tls->certificate_path = aws_jni_new_string_from_jstring(env, jni_custom_key_op_cert_path);
200*3c7ae9deSAndroid Build Coastguard Worker if (!tls->certificate_path) {
201*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(
202*3c7ae9deSAndroid Build Coastguard Worker env, "Custom key operation handler: failed to get certificate path string");
203*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
204*3c7ae9deSAndroid Build Coastguard Worker }
205*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_buf tmp_byte_buf;
206*3c7ae9deSAndroid Build Coastguard Worker int op = aws_byte_buf_init_from_file(&tmp_byte_buf, allocator, aws_string_c_str(tls->certificate_path));
207*3c7ae9deSAndroid Build Coastguard Worker if (op != AWS_OP_SUCCESS) {
208*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(
209*3c7ae9deSAndroid Build Coastguard Worker env, "Custom key operation handler: failed to get certificate path string");
210*3c7ae9deSAndroid Build Coastguard Worker aws_byte_buf_clean_up(&tmp_byte_buf);
211*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
212*3c7ae9deSAndroid Build Coastguard Worker }
213*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_cursor certificate_byte_cursor = aws_byte_cursor_from_buf(&tmp_byte_buf);
214*3c7ae9deSAndroid Build Coastguard Worker
215*3c7ae9deSAndroid Build Coastguard Worker /* Initialize the client with a custom key operation */
216*3c7ae9deSAndroid Build Coastguard Worker if (aws_tls_ctx_options_init_client_mtls_with_custom_key_operations(
217*3c7ae9deSAndroid Build Coastguard Worker &tls->options, allocator, tls->custom_key_op_handler, &certificate_byte_cursor) != AWS_OP_SUCCESS) {
218*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(
219*3c7ae9deSAndroid Build Coastguard Worker env, "aws_tls_ctx_options_init_client_mtls_with_custom_key_operations failed");
220*3c7ae9deSAndroid Build Coastguard Worker aws_byte_buf_clean_up(&tmp_byte_buf);
221*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
222*3c7ae9deSAndroid Build Coastguard Worker }
223*3c7ae9deSAndroid Build Coastguard Worker aws_byte_buf_clean_up(&tmp_byte_buf);
224*3c7ae9deSAndroid Build Coastguard Worker } else {
225*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "Custom key operation handler: No certificate set!");
226*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
227*3c7ae9deSAndroid Build Coastguard Worker }
228*3c7ae9deSAndroid Build Coastguard Worker
229*3c7ae9deSAndroid Build Coastguard Worker } else if (jni_pkcs12_path && jni_pkcs12_password) {
230*3c7ae9deSAndroid Build Coastguard Worker tls->pkcs12_path = aws_jni_new_string_from_jstring(env, jni_pkcs12_path);
231*3c7ae9deSAndroid Build Coastguard Worker if (!tls->pkcs12_path) {
232*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "failed to get pkcs12Path string");
233*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
234*3c7ae9deSAndroid Build Coastguard Worker }
235*3c7ae9deSAndroid Build Coastguard Worker tls->pkcs12_password = aws_jni_new_string_from_jstring(env, jni_pkcs12_password);
236*3c7ae9deSAndroid Build Coastguard Worker if (!tls->pkcs12_password) {
237*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "failed to get pkcs12Password string");
238*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
239*3c7ae9deSAndroid Build Coastguard Worker }
240*3c7ae9deSAndroid Build Coastguard Worker
241*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_cursor password = aws_byte_cursor_from_string(tls->pkcs12_password);
242*3c7ae9deSAndroid Build Coastguard Worker if (aws_tls_ctx_options_init_client_mtls_pkcs12_from_path(
243*3c7ae9deSAndroid Build Coastguard Worker &tls->options, allocator, aws_string_c_str(tls->pkcs12_path), &password)) {
244*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "aws_tls_ctx_options_init_client_mtls_pkcs12_from_path failed");
245*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
246*3c7ae9deSAndroid Build Coastguard Worker }
247*3c7ae9deSAndroid Build Coastguard Worker } else if (jni_windows_cert_store_path) {
248*3c7ae9deSAndroid Build Coastguard Worker tls->windows_cert_store_path = aws_jni_new_string_from_jstring(env, jni_windows_cert_store_path);
249*3c7ae9deSAndroid Build Coastguard Worker if (!tls->windows_cert_store_path) {
250*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "failed to get windowsCertStorePath string");
251*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
252*3c7ae9deSAndroid Build Coastguard Worker }
253*3c7ae9deSAndroid Build Coastguard Worker
254*3c7ae9deSAndroid Build Coastguard Worker if (aws_tls_ctx_options_init_client_mtls_from_system_path(
255*3c7ae9deSAndroid Build Coastguard Worker &tls->options, allocator, aws_string_c_str(tls->windows_cert_store_path))) {
256*3c7ae9deSAndroid Build Coastguard Worker
257*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "aws_tls_ctx_options_init_client_mtls_from_system_path failed");
258*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
259*3c7ae9deSAndroid Build Coastguard Worker }
260*3c7ae9deSAndroid Build Coastguard Worker }
261*3c7ae9deSAndroid Build Coastguard Worker
262*3c7ae9deSAndroid Build Coastguard Worker if (jni_ca) {
263*3c7ae9deSAndroid Build Coastguard Worker tls->ca_root = aws_jni_new_string_from_jstring(env, jni_ca);
264*3c7ae9deSAndroid Build Coastguard Worker if (!tls->ca_root) {
265*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "failed to get caRoot string");
266*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
267*3c7ae9deSAndroid Build Coastguard Worker }
268*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_cursor ca_cursor = aws_byte_cursor_from_string(tls->ca_root);
269*3c7ae9deSAndroid Build Coastguard Worker if (aws_tls_ctx_options_override_default_trust_store(&tls->options, &ca_cursor)) {
270*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "aws_tls_ctx_options_override_default_trust_store failed");
271*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
272*3c7ae9deSAndroid Build Coastguard Worker }
273*3c7ae9deSAndroid Build Coastguard Worker } else if (jni_ca_filepath || jni_ca_dirpath) {
274*3c7ae9deSAndroid Build Coastguard Worker const char *ca_file = NULL;
275*3c7ae9deSAndroid Build Coastguard Worker const char *ca_path = NULL;
276*3c7ae9deSAndroid Build Coastguard Worker if (jni_ca_filepath) {
277*3c7ae9deSAndroid Build Coastguard Worker tls->ca_file = aws_jni_new_string_from_jstring(env, jni_ca_filepath);
278*3c7ae9deSAndroid Build Coastguard Worker if (!tls->ca_file) {
279*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "failed to get caFile string");
280*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
281*3c7ae9deSAndroid Build Coastguard Worker }
282*3c7ae9deSAndroid Build Coastguard Worker
283*3c7ae9deSAndroid Build Coastguard Worker ca_file = aws_string_c_str(tls->ca_file);
284*3c7ae9deSAndroid Build Coastguard Worker }
285*3c7ae9deSAndroid Build Coastguard Worker if (jni_ca_dirpath) {
286*3c7ae9deSAndroid Build Coastguard Worker tls->ca_path = aws_jni_new_string_from_jstring(env, jni_ca_dirpath);
287*3c7ae9deSAndroid Build Coastguard Worker if (!tls->ca_path) {
288*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "failed to get caPath string");
289*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
290*3c7ae9deSAndroid Build Coastguard Worker }
291*3c7ae9deSAndroid Build Coastguard Worker
292*3c7ae9deSAndroid Build Coastguard Worker ca_path = aws_string_c_str(tls->ca_path);
293*3c7ae9deSAndroid Build Coastguard Worker }
294*3c7ae9deSAndroid Build Coastguard Worker
295*3c7ae9deSAndroid Build Coastguard Worker if (aws_tls_ctx_options_override_default_trust_store_from_path(&tls->options, ca_path, ca_file)) {
296*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "aws_tls_ctx_options_override_default_trust_store_from_path failed");
297*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
298*3c7ae9deSAndroid Build Coastguard Worker }
299*3c7ae9deSAndroid Build Coastguard Worker }
300*3c7ae9deSAndroid Build Coastguard Worker
301*3c7ae9deSAndroid Build Coastguard Worker /* apply the rest of the non-init settings */
302*3c7ae9deSAndroid Build Coastguard Worker tls->options.minimum_tls_version = (enum aws_tls_versions)jni_min_tls_version;
303*3c7ae9deSAndroid Build Coastguard Worker tls->options.cipher_pref = (enum aws_tls_cipher_pref)jni_cipher_pref;
304*3c7ae9deSAndroid Build Coastguard Worker tls->options.verify_peer = jni_verify_peer != 0;
305*3c7ae9deSAndroid Build Coastguard Worker
306*3c7ae9deSAndroid Build Coastguard Worker if (jni_alpn) {
307*3c7ae9deSAndroid Build Coastguard Worker tls->alpn_list = aws_jni_new_string_from_jstring(env, jni_alpn);
308*3c7ae9deSAndroid Build Coastguard Worker if (!tls->alpn_list) {
309*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "failed to get alpnList string");
310*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
311*3c7ae9deSAndroid Build Coastguard Worker }
312*3c7ae9deSAndroid Build Coastguard Worker
313*3c7ae9deSAndroid Build Coastguard Worker if (aws_tls_ctx_options_set_alpn_list(&tls->options, aws_string_c_str(tls->alpn_list))) {
314*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "aws_tls_ctx_options_set_alpn_list failed");
315*3c7ae9deSAndroid Build Coastguard Worker goto on_error;
316*3c7ae9deSAndroid Build Coastguard Worker }
317*3c7ae9deSAndroid Build Coastguard Worker }
318*3c7ae9deSAndroid Build Coastguard Worker
319*3c7ae9deSAndroid Build Coastguard Worker return (jlong)tls;
320*3c7ae9deSAndroid Build Coastguard Worker
321*3c7ae9deSAndroid Build Coastguard Worker on_error:
322*3c7ae9deSAndroid Build Coastguard Worker
323*3c7ae9deSAndroid Build Coastguard Worker s_jni_tls_ctx_options_destroy(tls);
324*3c7ae9deSAndroid Build Coastguard Worker
325*3c7ae9deSAndroid Build Coastguard Worker return (jlong)0;
326*3c7ae9deSAndroid Build Coastguard Worker }
327*3c7ae9deSAndroid Build Coastguard Worker
328*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT
Java_software_amazon_awssdk_crt_io_TlsContextOptions_tlsContextOptionsDestroy(JNIEnv * env,jclass jni_class,jlong jni_tls)329*3c7ae9deSAndroid Build Coastguard Worker void JNICALL Java_software_amazon_awssdk_crt_io_TlsContextOptions_tlsContextOptionsDestroy(
330*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
331*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
332*3c7ae9deSAndroid Build Coastguard Worker jlong jni_tls) {
333*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
334*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
335*3c7ae9deSAndroid Build Coastguard Worker
336*3c7ae9deSAndroid Build Coastguard Worker s_jni_tls_ctx_options_destroy((struct jni_tls_ctx_options *)jni_tls);
337*3c7ae9deSAndroid Build Coastguard Worker }
338*3c7ae9deSAndroid Build Coastguard Worker
339*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT
Java_software_amazon_awssdk_crt_io_TlsContextOptions_tlsContextOptionsIsAlpnAvailable(JNIEnv * env,jclass jni_class)340*3c7ae9deSAndroid Build Coastguard Worker jboolean JNICALL Java_software_amazon_awssdk_crt_io_TlsContextOptions_tlsContextOptionsIsAlpnAvailable(
341*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
342*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class) {
343*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
344*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
345*3c7ae9deSAndroid Build Coastguard Worker
346*3c7ae9deSAndroid Build Coastguard Worker return aws_tls_is_alpn_available();
347*3c7ae9deSAndroid Build Coastguard Worker }
348*3c7ae9deSAndroid Build Coastguard Worker
349*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT
Java_software_amazon_awssdk_crt_io_TlsContextOptions_tlsContextOptionsIsCipherPreferenceSupported(JNIEnv * env,jclass jni_class,jint jni_cipher_pref)350*3c7ae9deSAndroid Build Coastguard Worker jboolean JNICALL Java_software_amazon_awssdk_crt_io_TlsContextOptions_tlsContextOptionsIsCipherPreferenceSupported(
351*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
352*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
353*3c7ae9deSAndroid Build Coastguard Worker jint jni_cipher_pref) {
354*3c7ae9deSAndroid Build Coastguard Worker
355*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
356*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
357*3c7ae9deSAndroid Build Coastguard Worker
358*3c7ae9deSAndroid Build Coastguard Worker if (jni_cipher_pref < 0 || AWS_IO_TLS_CIPHER_PREF_END_RANGE <= jni_cipher_pref) {
359*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(
360*3c7ae9deSAndroid Build Coastguard Worker env,
361*3c7ae9deSAndroid Build Coastguard Worker "TlsContextOptions.tlsContextOptionsSetCipherPreference: TlsCipherPreference is out of range: %d",
362*3c7ae9deSAndroid Build Coastguard Worker (int)jni_cipher_pref);
363*3c7ae9deSAndroid Build Coastguard Worker return false;
364*3c7ae9deSAndroid Build Coastguard Worker }
365*3c7ae9deSAndroid Build Coastguard Worker
366*3c7ae9deSAndroid Build Coastguard Worker return aws_tls_is_cipher_pref_supported((enum aws_tls_cipher_pref)jni_cipher_pref);
367*3c7ae9deSAndroid Build Coastguard Worker }
368*3c7ae9deSAndroid Build Coastguard Worker
369*3c7ae9deSAndroid Build Coastguard Worker #if UINTPTR_MAX == 0xffffffff
370*3c7ae9deSAndroid Build Coastguard Worker # if defined(_MSC_VER)
371*3c7ae9deSAndroid Build Coastguard Worker # pragma warning(pop)
372*3c7ae9deSAndroid Build Coastguard Worker # else
373*3c7ae9deSAndroid Build Coastguard Worker # pragma GCC diagnostic pop
374*3c7ae9deSAndroid Build Coastguard Worker # endif
375*3c7ae9deSAndroid Build Coastguard Worker #endif
376