1 /*
2  * Copyright (C) 2023 The Android Open Source Project
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  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include "act_jni.h"
17 #include "jni_util.h"
18 #include <act/act_v0/act_v0.h>
19 #include <act/act_v0/parameters.h>
20 #include <act/util.pb.h>
21 #include <vector>
22 #include <google/protobuf/message_lite.h>
23 
24 
25 using namespace private_join_and_compute::anonymous_counting_tokens;
26 
27 
28 const char* IllegalArgumentExceptionClass = "java/lang/IllegalArgumentException";
29 const char* IllegalStateExceptionClass = "java/lang/IllegalStateException";
30 
31 
Java_com_android_adservices_ActJniWrapper_generateClientParameters(JNIEnv * env,jclass,jbyteArray scheme_parameter_bytes,jbyteArray server_public_parameters_bytes)32 JNIEXPORT jbyteArray JNICALL Java_com_android_adservices_ActJniWrapper_generateClientParameters(
33     JNIEnv *env,
34     jclass,
35     jbyteArray scheme_parameter_bytes,
36     jbyteArray server_public_parameters_bytes
37 ) {
38     SchemeParameters scheme_parameter_proto;
39     if(!jni_util::JniUtil::BytesToCppProto(env, &scheme_parameter_proto, scheme_parameter_bytes)) {
40         jni_util::JniUtil::ThrowJavaException(
41                 env, IllegalArgumentExceptionClass, "Error while parsing SchemeParameters Proto");
42         return nullptr;
43     }
44     ServerPublicParameters server_public_parameters_proto;
45     if(!jni_util::JniUtil::BytesToCppProto(env, &server_public_parameters_proto,
46                                                                  server_public_parameters_bytes)) {
47         jni_util::JniUtil::ThrowJavaException(
48                 env,
49                 IllegalArgumentExceptionClass,
50                 "Error while parsing ServerPublicParameters Proto");
51         return nullptr;
52     }
53 
54     std::unique_ptr<AnonymousCountingTokens> act = AnonymousCountingTokensV0::Create();
55 
56     ClientParameters client_parameters;
57     auto status_or
58         = (act -> GenerateClientParameters(scheme_parameter_proto, server_public_parameters_proto));
59     if(status_or.ok()) {
60         client_parameters = std::move(status_or).value();
61     } else {
62         jni_util::JniUtil::ThrowJavaException(
63                     env, IllegalArgumentExceptionClass, status_or.status().ToString().c_str());
64         return nullptr;
65     }
66     jbyteArray client_parameters_in_bytes =
67                             jni_util::JniUtil::SerializeProtoToJniByteArray(env, client_parameters);
68     return client_parameters_in_bytes;
69 }
70 
71 
Java_com_android_adservices_ActJniWrapper_generateTokensRequest(JNIEnv * env,jclass,jbyteArray messagesInBytes,jbyteArray schemeParametersInBytes,jbyteArray clientPublicParametersInBytes,jbyteArray clientPrivateParametersInBytes,jbyteArray serverPublicParametersInBytes)72 JNIEXPORT jbyteArray JNICALL Java_com_android_adservices_ActJniWrapper_generateTokensRequest(
73     JNIEnv *env,
74     jclass,
75     jbyteArray messagesInBytes,
76     jbyteArray schemeParametersInBytes,
77     jbyteArray clientPublicParametersInBytes,
78     jbyteArray clientPrivateParametersInBytes,
79     jbyteArray serverPublicParametersInBytes
80 ) {
81     MessagesSet messagesProto;
82     if(!jni_util::JniUtil::BytesToCppProto(env, &messagesProto, messagesInBytes)) {
83         jni_util::JniUtil::ThrowJavaException(
84                 env, IllegalArgumentExceptionClass, "Error parsing MessagesSet Proto");
85         return nullptr;
86     }
87     std::vector<std::string> messagesVector(messagesProto.message_size());
88     for(int i = 0; i < messagesProto.message_size(); i++) {
89         messagesVector[i] = messagesProto.message(i);
90     }
91 
92     SchemeParameters schemeParametersProto;
93     if(!jni_util::JniUtil::BytesToCppProto(env, &schemeParametersProto, schemeParametersInBytes)) {
94         jni_util::JniUtil::ThrowJavaException(
95                 env, IllegalArgumentExceptionClass, "Error parsing SchemeParameters Proto");
96         return nullptr;
97     }
98     ClientPublicParameters clientPublicParametersProto;
99     if(!jni_util::JniUtil::BytesToCppProto(env, &clientPublicParametersProto,
100                                                                 clientPublicParametersInBytes)) {
101         jni_util::JniUtil::ThrowJavaException(
102             env, IllegalArgumentExceptionClass, "Error parsing ClientPublicParameters Proto");
103         return nullptr;
104     }
105     ClientPrivateParameters clientPrivateParametersProto;
106     if(!jni_util::JniUtil::BytesToCppProto(env, &clientPrivateParametersProto,
107                                                                clientPrivateParametersInBytes)) {
108         jni_util::JniUtil::ThrowJavaException(
109             env, IllegalArgumentExceptionClass, "Error parsing ClientPrivateParameters Proto");
110 
111         return nullptr;
112     }
113     ServerPublicParameters serverPublicParametersProto;
114     if(!jni_util::JniUtil::BytesToCppProto(env, &serverPublicParametersProto,
115                                                                 serverPublicParametersInBytes)) {
116         jni_util::JniUtil::ThrowJavaException(
117             env, IllegalArgumentExceptionClass, "Error parsing ServerPublicParameters Proto");
118         return nullptr;
119     }
120 
121     std::unique_ptr<AnonymousCountingTokens> act = AnonymousCountingTokensV0::Create();
122     auto status_or = (act -> GenerateTokensRequest(
123                                               messagesVector,
124                                               schemeParametersProto,
125                                               clientPublicParametersProto,
126                                               clientPrivateParametersProto,
127                                               serverPublicParametersProto));
128     if (!status_or.ok()) {
129         jni_util::JniUtil::ThrowJavaException(
130                     env, IllegalStateExceptionClass, status_or.status().ToString().c_str());
131         return nullptr;
132     }
133 
134     std::tuple<std::vector<std::string>, TokensRequest, TokensRequestPrivateState> response
135                                                                     = std::move(status_or).value();
136 
137     std::vector<std::string> fingerprint_bytes = std::get<0>(response);
138     TokensRequest token_request_temp = std::get<1>(response);
139     TokensRequestPrivateState tokens_request_private_state_temp = std::get<2>(response);
140 
141     GeneratedTokensRequestProto generated_tokens_request_proto;
142     for(auto& fingerprint: fingerprint_bytes) {
143         generated_tokens_request_proto.add_fingerprints_bytes(fingerprint);
144     }
145     TokensRequest* token_request = new TokensRequest(token_request_temp);
146     generated_tokens_request_proto.set_allocated_token_request(token_request);
147     TokensRequestPrivateState* tokens_request_private_state
148                             = new TokensRequestPrivateState(tokens_request_private_state_temp);
149     generated_tokens_request_proto
150                         .set_allocated_tokens_request_private_state(tokens_request_private_state);
151 
152     return jni_util::JniUtil::SerializeProtoToJniByteArray(env, generated_tokens_request_proto);
153 }
154 
Java_com_android_adservices_ActJniWrapper_verifyTokensResponse(JNIEnv * env,jclass,jbyteArray messagesInBytes,jbyteArray tokenRequestInBytes,jbyteArray tokensRequestPrivateStateInBytes,jbyteArray tokensResponseInBytes,jbyteArray schemeParametersInBytes,jbyteArray clientPublicParametersInBytes,jbyteArray clientPrivateParametersInBytes,jbyteArray serverPublicParametersInBytes)155 JNIEXPORT jboolean JNICALL Java_com_android_adservices_ActJniWrapper_verifyTokensResponse(
156     JNIEnv *env,
157     jclass,
158     jbyteArray messagesInBytes,
159     jbyteArray tokenRequestInBytes,
160     jbyteArray tokensRequestPrivateStateInBytes,
161     jbyteArray tokensResponseInBytes,
162     jbyteArray schemeParametersInBytes,
163     jbyteArray clientPublicParametersInBytes,
164     jbyteArray clientPrivateParametersInBytes,
165     jbyteArray serverPublicParametersInBytes
166 ) {
167     MessagesSet messagesProto;
168     if(!jni_util::JniUtil::BytesToCppProto(env, &messagesProto, messagesInBytes)) {
169         jni_util::JniUtil::ThrowJavaException(
170                     env, IllegalArgumentExceptionClass, "Error parsing MessagesSet Proto");
171         return false;
172     }
173     std::vector<std::string> messagesVector(messagesProto.message_size());
174     for(int i = 0; i < messagesProto.message_size(); i++) {
175         messagesVector[i] = messagesProto.message(i);
176     }
177 
178     TokensRequest tokenRequestProto;
179     if(!jni_util::JniUtil::BytesToCppProto(env, &tokenRequestProto, tokenRequestInBytes)) {
180         jni_util::JniUtil::ThrowJavaException(
181                     env, IllegalArgumentExceptionClass, "Error parsing TokensRequest Proto");
182         return false;
183     }
184 
185     TokensRequestPrivateState tokensRequestPrivateStateProto;
186     if(!jni_util::JniUtil::BytesToCppProto(env, &tokensRequestPrivateStateProto,
187                                                               tokensRequestPrivateStateInBytes)) {
188         jni_util::JniUtil::ThrowJavaException(
189             env, IllegalArgumentExceptionClass, "Error parsing TokensRequestPrivateState Proto");
190         return false;
191     }
192 
193     TokensResponse tokensResponseProto;
194     if(!jni_util::JniUtil::BytesToCppProto(env, &tokensResponseProto, tokensResponseInBytes)) {
195         jni_util::JniUtil::ThrowJavaException(
196             env, IllegalArgumentExceptionClass, "Error parsing TokensResponse Proto");
197         return false;
198     }
199 
200     SchemeParameters schemeParametersProto;
201     if(!jni_util::JniUtil::BytesToCppProto(env, &schemeParametersProto, schemeParametersInBytes)) {
202         jni_util::JniUtil::ThrowJavaException(
203                     env, IllegalArgumentExceptionClass, "Error parsing SchemeParameters Proto");
204         return false;
205     }
206     ClientPublicParameters clientPublicParametersProto;
207     if(!jni_util::JniUtil::BytesToCppProto(env, &clientPublicParametersProto,
208                                                                 clientPublicParametersInBytes)) {
209         jni_util::JniUtil::ThrowJavaException(
210             env, IllegalArgumentExceptionClass, "Error parsing ClientPublicParameters Proto");
211         return false;
212     }
213     ClientPrivateParameters clientPrivateParametersProto;
214     if(!jni_util::JniUtil::BytesToCppProto(env, &clientPrivateParametersProto,
215                                                                 clientPublicParametersInBytes)) {
216         jni_util::JniUtil::ThrowJavaException(
217             env, IllegalArgumentExceptionClass, "Error parsing ClientPublicParameters Proto");
218         return false;
219     }
220     ServerPublicParameters serverPublicParametersProto;
221     if(!jni_util::JniUtil::BytesToCppProto(env, &serverPublicParametersProto,
222                                                                 serverPublicParametersInBytes)) {
223         jni_util::JniUtil::ThrowJavaException(
224             env, IllegalArgumentExceptionClass, "Error parsing ClientPublicParameters Proto");
225         return false;
226     }
227 
228     std::unique_ptr<AnonymousCountingTokens> act = AnonymousCountingTokensV0::Create();
229 
230     auto status = (act -> VerifyTokensResponse(
231                                               messagesVector,
232                                               tokenRequestProto,
233                                               tokensRequestPrivateStateProto,
234                                               tokensResponseProto,
235                                               schemeParametersProto,
236                                               clientPublicParametersProto,
237                                               clientPrivateParametersProto,
238                                               serverPublicParametersProto));
239 
240     if(status.ok()) {
241         return true;
242     } else {
243         jni_util::JniUtil::ThrowJavaException(
244                     env, IllegalStateExceptionClass, status.ToString().c_str());
245         return false;
246     }
247 }
248 
249 
Java_com_android_adservices_ActJniWrapper_recoverTokens(JNIEnv * env,jclass,jbyteArray messagesInBytes,jbyteArray tokenRequestInBytes,jbyteArray tokensRequestPrivateStateInBytes,jbyteArray tokensResponseInBytes,jbyteArray schemeParametersInBytes,jbyteArray clientPublicParametersInBytes,jbyteArray clientPrivateParametersInBytes,jbyteArray serverPublicParametersInBytes)250 JNIEXPORT jbyteArray JNICALL Java_com_android_adservices_ActJniWrapper_recoverTokens(
251     JNIEnv *env,
252     jclass,
253     jbyteArray messagesInBytes,
254     jbyteArray tokenRequestInBytes,
255     jbyteArray tokensRequestPrivateStateInBytes,
256     jbyteArray tokensResponseInBytes,
257     jbyteArray schemeParametersInBytes,
258     jbyteArray clientPublicParametersInBytes,
259     jbyteArray clientPrivateParametersInBytes,
260     jbyteArray serverPublicParametersInBytes
261 ) {
262     MessagesSet messagesProto;
263     if(!jni_util::JniUtil::BytesToCppProto(env, &messagesProto, messagesInBytes)) {
264         jni_util::JniUtil::ThrowJavaException(
265             env, IllegalArgumentExceptionClass, "Error parsing MessagesSet Proto");
266         return nullptr;
267     }
268     std::vector<std::string> messagesVector(messagesProto.message_size());
269     for(int i = 0; i < messagesProto.message_size(); i++) {
270         messagesVector[i] = messagesProto.message(i);
271     }
272 
273     TokensRequest tokenRequestProto;
274     if(!jni_util::JniUtil::BytesToCppProto(env, &tokenRequestProto, tokenRequestInBytes)) {
275         jni_util::JniUtil::ThrowJavaException(
276             env, IllegalArgumentExceptionClass, "Error parsing TokensRequest Proto");
277         return nullptr;
278     }
279 
280     TokensRequestPrivateState tokensRequestPrivateStateProto;
281     if(!jni_util::JniUtil::BytesToCppProto(
282                 env, &tokensRequestPrivateStateProto, tokensRequestPrivateStateInBytes)) {
283         jni_util::JniUtil::ThrowJavaException(
284             env, IllegalArgumentExceptionClass, "Error parsing TokensRequestPrivateState Proto");
285         return nullptr;
286     }
287 
288     TokensResponse tokensResponseProto;
289     if(!jni_util::JniUtil::BytesToCppProto(env, &tokensResponseProto, tokensResponseInBytes)) {
290         jni_util::JniUtil::ThrowJavaException(
291             env, IllegalArgumentExceptionClass, "Error parsing TokensResponse Proto");
292         return nullptr;
293     }
294 
295     SchemeParameters schemeParametersProto;
296     if(!jni_util::JniUtil::BytesToCppProto(
297             env, &schemeParametersProto, schemeParametersInBytes)) {
298         jni_util::JniUtil::ThrowJavaException(
299             env, IllegalArgumentExceptionClass, "Error parsing SchemeParameters Proto");
300         return nullptr;
301     }
302     ClientPublicParameters clientPublicParametersProto;
303     if(!jni_util::JniUtil::BytesToCppProto(
304                 env, &clientPublicParametersProto, clientPublicParametersInBytes)) {
305         jni_util::JniUtil::ThrowJavaException(
306             env, IllegalArgumentExceptionClass, "Error parsing ClientPublicParameters Proto");
307         return nullptr;
308     }
309     ClientPrivateParameters clientPrivateParametersProto;
310     if(!jni_util::JniUtil::BytesToCppProto(
311                 env, &clientPrivateParametersProto, clientPublicParametersInBytes)) {
312         jni_util::JniUtil::ThrowJavaException(
313             env, IllegalArgumentExceptionClass, "Error parsing SchemeParameters Proto");
314         return nullptr;
315     }
316     ServerPublicParameters serverPublicParametersProto;
317     if(!jni_util::JniUtil::BytesToCppProto(
318                     env, &serverPublicParametersProto, serverPublicParametersInBytes)) {
319         jni_util::JniUtil::ThrowJavaException(
320             env, IllegalArgumentExceptionClass, "Error parsing ServerPublicParameters Proto");
321         return nullptr;
322     }
323 
324     std::unique_ptr<AnonymousCountingTokens> act = AnonymousCountingTokensV0::Create();
325 
326     auto status_or = (act -> RecoverTokens(
327                                               messagesVector,
328                                               tokenRequestProto,
329                                               tokensRequestPrivateStateProto,
330                                               tokensResponseProto,
331                                               schemeParametersProto,
332                                               clientPublicParametersProto,
333                                               clientPrivateParametersProto,
334                                               serverPublicParametersProto));
335 
336 
337 
338     if (!status_or.ok()) {
339         jni_util::JniUtil::ThrowJavaException(
340                     env, IllegalArgumentExceptionClass, status_or.status().ToString().c_str());
341         return nullptr;
342     }
343     std::vector<Token> tokens = std::move(status_or).value();
344     TokensSet tokens_set_proto;
345     *tokens_set_proto.mutable_tokens() = {tokens.begin(), tokens.end()};
346     return jni_util::JniUtil::SerializeProtoToJniByteArray(env, tokens_set_proto);
347 }
348 
349