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 "crt.h"
7*3c7ae9deSAndroid Build Coastguard Worker #include "java_class_ids.h"
8*3c7ae9deSAndroid Build Coastguard Worker
9*3c7ae9deSAndroid Build Coastguard Worker #include <aws/auth/credentials.h>
10*3c7ae9deSAndroid Build Coastguard Worker
11*3c7ae9deSAndroid Build Coastguard Worker /* on 32-bit platforms, casting pointers to longs throws a warning we don't need */
12*3c7ae9deSAndroid Build Coastguard Worker #if UINTPTR_MAX == 0xffffffff
13*3c7ae9deSAndroid Build Coastguard Worker # if defined(_MSC_VER)
14*3c7ae9deSAndroid Build Coastguard Worker # pragma warning(push)
15*3c7ae9deSAndroid Build Coastguard Worker # pragma warning(disable : 4305) /* 'type cast': truncation from 'jlong' to 'jni_tls_ctx_options *' */
16*3c7ae9deSAndroid Build Coastguard Worker # else
17*3c7ae9deSAndroid Build Coastguard Worker # pragma GCC diagnostic push
18*3c7ae9deSAndroid Build Coastguard Worker # pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
19*3c7ae9deSAndroid Build Coastguard Worker # pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
20*3c7ae9deSAndroid Build Coastguard Worker # endif
21*3c7ae9deSAndroid Build Coastguard Worker #endif
22*3c7ae9deSAndroid Build Coastguard Worker
aws_credentials_new_from_java_credentials(JNIEnv * env,jobject java_credentials)23*3c7ae9deSAndroid Build Coastguard Worker struct aws_credentials *aws_credentials_new_from_java_credentials(JNIEnv *env, jobject java_credentials) {
24*3c7ae9deSAndroid Build Coastguard Worker if (java_credentials == NULL) {
25*3c7ae9deSAndroid Build Coastguard Worker return NULL;
26*3c7ae9deSAndroid Build Coastguard Worker }
27*3c7ae9deSAndroid Build Coastguard Worker struct aws_credentials *credentials = NULL;
28*3c7ae9deSAndroid Build Coastguard Worker
29*3c7ae9deSAndroid Build Coastguard Worker jbyteArray access_key_id =
30*3c7ae9deSAndroid Build Coastguard Worker (*env)->GetObjectField(env, java_credentials, credentials_properties.access_key_id_field_id);
31*3c7ae9deSAndroid Build Coastguard Worker jbyteArray secret_access_key =
32*3c7ae9deSAndroid Build Coastguard Worker (*env)->GetObjectField(env, java_credentials, credentials_properties.secret_access_key_field_id);
33*3c7ae9deSAndroid Build Coastguard Worker jbyteArray session_token =
34*3c7ae9deSAndroid Build Coastguard Worker (*env)->GetObjectField(env, java_credentials, credentials_properties.session_token_field_id);
35*3c7ae9deSAndroid Build Coastguard Worker
36*3c7ae9deSAndroid Build Coastguard Worker jlong expiration_timepoint_secs =
37*3c7ae9deSAndroid Build Coastguard Worker (*env)->GetLongField(env, java_credentials, credentials_properties.expiration_field_id);
38*3c7ae9deSAndroid Build Coastguard Worker
39*3c7ae9deSAndroid Build Coastguard Worker if (access_key_id == NULL && secret_access_key == NULL) {
40*3c7ae9deSAndroid Build Coastguard Worker credentials = aws_credentials_new_anonymous(aws_jni_get_allocator());
41*3c7ae9deSAndroid Build Coastguard Worker goto done;
42*3c7ae9deSAndroid Build Coastguard Worker }
43*3c7ae9deSAndroid Build Coastguard Worker
44*3c7ae9deSAndroid Build Coastguard Worker if (access_key_id == NULL || secret_access_key == NULL) {
45*3c7ae9deSAndroid Build Coastguard Worker aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
46*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_illegal_argument_exception(
47*3c7ae9deSAndroid Build Coastguard Worker env,
48*3c7ae9deSAndroid Build Coastguard Worker "Aws_credentials_new_from_java_credentials: Both access_key_id and secret_access_key must be either null "
49*3c7ae9deSAndroid Build Coastguard Worker "or non-null.");
50*3c7ae9deSAndroid Build Coastguard Worker goto done;
51*3c7ae9deSAndroid Build Coastguard Worker }
52*3c7ae9deSAndroid Build Coastguard Worker
53*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_cursor access_key_id_cursor = aws_jni_byte_cursor_from_jbyteArray_acquire(env, access_key_id);
54*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_cursor secret_access_key_cursor =
55*3c7ae9deSAndroid Build Coastguard Worker aws_jni_byte_cursor_from_jbyteArray_acquire(env, secret_access_key);
56*3c7ae9deSAndroid Build Coastguard Worker
57*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_cursor session_token_cursor;
58*3c7ae9deSAndroid Build Coastguard Worker AWS_ZERO_STRUCT(session_token_cursor);
59*3c7ae9deSAndroid Build Coastguard Worker if (session_token != NULL) {
60*3c7ae9deSAndroid Build Coastguard Worker session_token_cursor = aws_jni_byte_cursor_from_jbyteArray_acquire(env, session_token);
61*3c7ae9deSAndroid Build Coastguard Worker }
62*3c7ae9deSAndroid Build Coastguard Worker
63*3c7ae9deSAndroid Build Coastguard Worker credentials = aws_credentials_new(
64*3c7ae9deSAndroid Build Coastguard Worker aws_jni_get_allocator(),
65*3c7ae9deSAndroid Build Coastguard Worker access_key_id_cursor,
66*3c7ae9deSAndroid Build Coastguard Worker secret_access_key_cursor,
67*3c7ae9deSAndroid Build Coastguard Worker session_token_cursor,
68*3c7ae9deSAndroid Build Coastguard Worker (uint64_t)expiration_timepoint_secs);
69*3c7ae9deSAndroid Build Coastguard Worker
70*3c7ae9deSAndroid Build Coastguard Worker aws_jni_byte_cursor_from_jbyteArray_release(env, access_key_id, access_key_id_cursor);
71*3c7ae9deSAndroid Build Coastguard Worker aws_jni_byte_cursor_from_jbyteArray_release(env, secret_access_key, secret_access_key_cursor);
72*3c7ae9deSAndroid Build Coastguard Worker if (session_token != NULL) {
73*3c7ae9deSAndroid Build Coastguard Worker aws_jni_byte_cursor_from_jbyteArray_release(env, session_token, session_token_cursor);
74*3c7ae9deSAndroid Build Coastguard Worker }
75*3c7ae9deSAndroid Build Coastguard Worker
76*3c7ae9deSAndroid Build Coastguard Worker done:
77*3c7ae9deSAndroid Build Coastguard Worker /* When local references are created by a thread from C, the JVM does not clean them up promptly. */
78*3c7ae9deSAndroid Build Coastguard Worker if (access_key_id) {
79*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteLocalRef(env, access_key_id);
80*3c7ae9deSAndroid Build Coastguard Worker }
81*3c7ae9deSAndroid Build Coastguard Worker if (secret_access_key) {
82*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteLocalRef(env, secret_access_key);
83*3c7ae9deSAndroid Build Coastguard Worker }
84*3c7ae9deSAndroid Build Coastguard Worker if (session_token) {
85*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteLocalRef(env, session_token);
86*3c7ae9deSAndroid Build Coastguard Worker }
87*3c7ae9deSAndroid Build Coastguard Worker return credentials;
88*3c7ae9deSAndroid Build Coastguard Worker }
89*3c7ae9deSAndroid Build Coastguard Worker
aws_java_credentials_from_native_new(JNIEnv * env,const struct aws_credentials * credentials)90*3c7ae9deSAndroid Build Coastguard Worker jobject aws_java_credentials_from_native_new(JNIEnv *env, const struct aws_credentials *credentials) {
91*3c7ae9deSAndroid Build Coastguard Worker
92*3c7ae9deSAndroid Build Coastguard Worker jobject java_credentials = NULL;
93*3c7ae9deSAndroid Build Coastguard Worker jbyteArray access_key_id = NULL;
94*3c7ae9deSAndroid Build Coastguard Worker jbyteArray secret_access_key = NULL;
95*3c7ae9deSAndroid Build Coastguard Worker jbyteArray session_token = NULL;
96*3c7ae9deSAndroid Build Coastguard Worker java_credentials =
97*3c7ae9deSAndroid Build Coastguard Worker (*env)->NewObject(env, credentials_properties.credentials_class, credentials_properties.constructor_method_id);
98*3c7ae9deSAndroid Build Coastguard Worker if (java_credentials != NULL) {
99*3c7ae9deSAndroid Build Coastguard Worker
100*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_cursor access_key_id_cursor = aws_credentials_get_access_key_id(credentials);
101*3c7ae9deSAndroid Build Coastguard Worker if (access_key_id_cursor.len > 0) {
102*3c7ae9deSAndroid Build Coastguard Worker access_key_id = aws_jni_byte_array_from_cursor(env, &access_key_id_cursor);
103*3c7ae9deSAndroid Build Coastguard Worker }
104*3c7ae9deSAndroid Build Coastguard Worker
105*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_cursor secret_access_key_cursor = aws_credentials_get_secret_access_key(credentials);
106*3c7ae9deSAndroid Build Coastguard Worker if (secret_access_key_cursor.len > 0) {
107*3c7ae9deSAndroid Build Coastguard Worker secret_access_key = aws_jni_byte_array_from_cursor(env, &secret_access_key_cursor);
108*3c7ae9deSAndroid Build Coastguard Worker }
109*3c7ae9deSAndroid Build Coastguard Worker
110*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_cursor session_token_cursor = aws_credentials_get_session_token(credentials);
111*3c7ae9deSAndroid Build Coastguard Worker if (session_token_cursor.len > 0) {
112*3c7ae9deSAndroid Build Coastguard Worker session_token = aws_jni_byte_array_from_cursor(env, &session_token_cursor);
113*3c7ae9deSAndroid Build Coastguard Worker }
114*3c7ae9deSAndroid Build Coastguard Worker
115*3c7ae9deSAndroid Build Coastguard Worker (*env)->SetObjectField(env, java_credentials, credentials_properties.access_key_id_field_id, access_key_id);
116*3c7ae9deSAndroid Build Coastguard Worker (*env)->SetObjectField(
117*3c7ae9deSAndroid Build Coastguard Worker env, java_credentials, credentials_properties.secret_access_key_field_id, secret_access_key);
118*3c7ae9deSAndroid Build Coastguard Worker if (session_token != NULL) {
119*3c7ae9deSAndroid Build Coastguard Worker (*env)->SetObjectField(env, java_credentials, credentials_properties.session_token_field_id, session_token);
120*3c7ae9deSAndroid Build Coastguard Worker }
121*3c7ae9deSAndroid Build Coastguard Worker (*env)->SetLongField(
122*3c7ae9deSAndroid Build Coastguard Worker env,
123*3c7ae9deSAndroid Build Coastguard Worker java_credentials,
124*3c7ae9deSAndroid Build Coastguard Worker credentials_properties.expiration_field_id,
125*3c7ae9deSAndroid Build Coastguard Worker (jlong)aws_credentials_get_expiration_timepoint_seconds(credentials));
126*3c7ae9deSAndroid Build Coastguard Worker } else {
127*3c7ae9deSAndroid Build Coastguard Worker return NULL;
128*3c7ae9deSAndroid Build Coastguard Worker }
129*3c7ae9deSAndroid Build Coastguard Worker
130*3c7ae9deSAndroid Build Coastguard Worker if (access_key_id) {
131*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteLocalRef(env, access_key_id);
132*3c7ae9deSAndroid Build Coastguard Worker }
133*3c7ae9deSAndroid Build Coastguard Worker if (secret_access_key) {
134*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteLocalRef(env, secret_access_key);
135*3c7ae9deSAndroid Build Coastguard Worker }
136*3c7ae9deSAndroid Build Coastguard Worker if (session_token) {
137*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteLocalRef(env, session_token);
138*3c7ae9deSAndroid Build Coastguard Worker }
139*3c7ae9deSAndroid Build Coastguard Worker
140*3c7ae9deSAndroid Build Coastguard Worker return java_credentials;
141*3c7ae9deSAndroid Build Coastguard Worker }
142*3c7ae9deSAndroid Build Coastguard Worker
143*3c7ae9deSAndroid Build Coastguard Worker #if UINTPTR_MAX == 0xffffffff
144*3c7ae9deSAndroid Build Coastguard Worker # if defined(_MSC_VER)
145*3c7ae9deSAndroid Build Coastguard Worker # pragma warning(pop)
146*3c7ae9deSAndroid Build Coastguard Worker # else
147*3c7ae9deSAndroid Build Coastguard Worker # pragma GCC diagnostic pop
148*3c7ae9deSAndroid Build Coastguard Worker # endif
149*3c7ae9deSAndroid Build Coastguard Worker #endif
150