xref: /aosp_15_r20/external/aws-crt-java/src/native/ecc_key_pair.c (revision 3c7ae9de214676c52d19f01067dc1a404272dc11)
1 /*
2  * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License").
5  * You may not use this file except in compliance with the License.
6  * A copy of the License is located at
7  *
8  *  http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */
15 
16 #include <jni.h>
17 
18 #include <aws/auth/credentials.h>
19 #include <aws/cal/ecc.h>
20 
21 #include "credentials.h"
22 #include "crt.h"
23 #include "java_class_ids.h"
24 
25 /* on 32-bit platforms, casting pointers to longs throws a warning we don't need */
26 #if UINTPTR_MAX == 0xffffffff
27 #    if defined(_MSC_VER)
28 #        pragma warning(push)
29 #        pragma warning(disable : 4305) /* 'type cast': truncation from 'jlong' to 'jni_tls_ctx_options *' */
30 #    else
31 #        pragma GCC diagnostic push
32 #        pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
33 #        pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
34 #    endif
35 #endif
36 
37 JNIEXPORT
38 void JNICALL
Java_software_amazon_awssdk_crt_cal_EccKeyPair_eccKeyPairRelease(JNIEnv * env,jclass jni_ekp,jlong ekp_addr)39     Java_software_amazon_awssdk_crt_cal_EccKeyPair_eccKeyPairRelease(JNIEnv *env, jclass jni_ekp, jlong ekp_addr) {
40     (void)jni_ekp;
41     aws_cache_jni_ids(env);
42 
43     struct aws_ecc_key_pair *key_pair = (struct aws_ecc_key_pair *)ekp_addr;
44 
45     aws_ecc_key_pair_release(key_pair);
46 }
47 
48 JNIEXPORT
Java_software_amazon_awssdk_crt_cal_EccKeyPair_eccKeyPairNewFromCredentials(JNIEnv * env,jclass jni_class,jobject credentials,jint curve)49 jlong JNICALL Java_software_amazon_awssdk_crt_cal_EccKeyPair_eccKeyPairNewFromCredentials(
50     JNIEnv *env,
51     jclass jni_class,
52     jobject credentials,
53     jint curve) {
54 
55     (void)jni_class;
56     aws_cache_jni_ids(env);
57 
58     struct aws_credentials *native_credentials = aws_credentials_new_from_java_credentials(env, credentials);
59     if (native_credentials == NULL) {
60         return (jlong)0;
61     }
62 
63     enum aws_ecc_curve_name curve_name = curve;
64 
65     struct aws_ecc_key_pair *key_pair = NULL;
66 
67     switch (curve_name) {
68         case AWS_CAL_ECDSA_P256:
69             key_pair =
70                 aws_ecc_key_pair_new_ecdsa_p256_key_from_aws_credentials(aws_jni_get_allocator(), native_credentials);
71             break;
72 
73         default:
74             break;
75     }
76 
77     aws_credentials_release(native_credentials);
78 
79     AWS_FATAL_ASSERT(!(*env)->ExceptionCheck(env));
80 
81     return (jlong)key_pair;
82 }
83 
84 #define SIGNATURE_SIZE_OVERESTIMATE 128
85 
86 JNIEXPORT
Java_software_amazon_awssdk_crt_cal_EccKeyPair_eccKeyPairSignMessage(JNIEnv * env,jclass jni_class,jlong ekp_addr,jbyteArray message)87 jbyteArray JNICALL Java_software_amazon_awssdk_crt_cal_EccKeyPair_eccKeyPairSignMessage(
88     JNIEnv *env,
89     jclass jni_class,
90     jlong ekp_addr,
91     jbyteArray message) {
92 
93     (void)jni_class;
94     aws_cache_jni_ids(env);
95 
96     struct aws_ecc_key_pair *key_pair = (struct aws_ecc_key_pair *)ekp_addr;
97 
98     struct aws_byte_buf signature_buffer;
99     AWS_ZERO_STRUCT(signature_buffer);
100 
101     if (aws_byte_buf_init(&signature_buffer, aws_jni_get_allocator(), SIGNATURE_SIZE_OVERESTIMATE)) {
102         aws_jni_throw_runtime_exception(env, "EccKeyPair.eccKeyPairSignMessage: failed to initialize signature buffer");
103         return NULL;
104     }
105 
106     struct aws_byte_cursor message_cursor = aws_jni_byte_cursor_from_jbyteArray_acquire(env, message);
107     if (message_cursor.ptr == NULL) {
108         aws_jni_throw_runtime_exception(env, "EccKeyPair.eccKeyPairSignMessage: failed to pin message bytes");
109         return NULL;
110     }
111 
112     jbyteArray signature = NULL;
113     if (aws_ecc_key_pair_sign_message(key_pair, &message_cursor, &signature_buffer)) {
114         aws_jni_throw_runtime_exception(env, "EccKeyPair.eccKeyPairSignMessage: failed to sign message");
115     } else {
116         struct aws_byte_cursor signature_cursor = aws_byte_cursor_from_buf(&signature_buffer);
117         signature = aws_jni_byte_array_from_cursor(env, &signature_cursor);
118     }
119 
120     aws_jni_byte_cursor_from_jbyteArray_release(env, message, message_cursor);
121     aws_byte_buf_clean_up(&signature_buffer);
122 
123     return signature;
124 }
125 
126 #if UINTPTR_MAX == 0xffffffff
127 #    if defined(_MSC_VER)
128 #        pragma warning(pop)
129 #    else
130 #        pragma GCC diagnostic pop
131 #    endif
132 #endif
133