xref: /aosp_15_r20/external/aws-crt-java/src/native/credentials.c (revision 3c7ae9de214676c52d19f01067dc1a404272dc11)
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