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