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