1 // Copyright 2019 The BoringSSL Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <openssl/bytestring.h>
16 #include <openssl/err.h>
17 #include <openssl/evp.h>
18 #include <openssl/mem.h>
19 #include <openssl/sha2.h>
20 #include <openssl/trust_token.h>
21
22 #include "internal.h"
23
24
25 // The Trust Token API is described in
26 // https://github.com/WICG/trust-token-api/blob/main/README.md and provides a
27 // protocol for issuing and redeeming tokens built on top of the PMBTokens
28 // construction.
29
TRUST_TOKEN_experiment_v1(void)30 const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v1(void) {
31 static const TRUST_TOKEN_METHOD kMethod = {
32 pmbtoken_exp1_generate_key,
33 pmbtoken_exp1_derive_key_from_secret,
34 pmbtoken_exp1_client_key_from_bytes,
35 pmbtoken_exp1_issuer_key_from_bytes,
36 pmbtoken_exp1_blind,
37 pmbtoken_exp1_sign,
38 pmbtoken_exp1_unblind,
39 pmbtoken_exp1_read,
40 1, /* has_private_metadata */
41 3, /* max_keys */
42 1, /* has_srr */
43 };
44 return &kMethod;
45 }
46
TRUST_TOKEN_experiment_v2_voprf(void)47 const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v2_voprf(void) {
48 static const TRUST_TOKEN_METHOD kMethod = {
49 voprf_exp2_generate_key,
50 voprf_exp2_derive_key_from_secret,
51 voprf_exp2_client_key_from_bytes,
52 voprf_exp2_issuer_key_from_bytes,
53 voprf_exp2_blind,
54 voprf_exp2_sign,
55 voprf_exp2_unblind,
56 voprf_exp2_read,
57 0, /* has_private_metadata */
58 6, /* max_keys */
59 0, /* has_srr */
60 };
61 return &kMethod;
62 }
63
TRUST_TOKEN_experiment_v2_pmb(void)64 const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v2_pmb(void) {
65 static const TRUST_TOKEN_METHOD kMethod = {
66 pmbtoken_exp2_generate_key,
67 pmbtoken_exp2_derive_key_from_secret,
68 pmbtoken_exp2_client_key_from_bytes,
69 pmbtoken_exp2_issuer_key_from_bytes,
70 pmbtoken_exp2_blind,
71 pmbtoken_exp2_sign,
72 pmbtoken_exp2_unblind,
73 pmbtoken_exp2_read,
74 1, /* has_private_metadata */
75 3, /* max_keys */
76 0, /* has_srr */
77 };
78 return &kMethod;
79 }
80
TRUST_TOKEN_pst_v1_voprf(void)81 const TRUST_TOKEN_METHOD *TRUST_TOKEN_pst_v1_voprf(void) {
82 static const TRUST_TOKEN_METHOD kMethod = {
83 voprf_pst1_generate_key,
84 voprf_pst1_derive_key_from_secret,
85 voprf_pst1_client_key_from_bytes,
86 voprf_pst1_issuer_key_from_bytes,
87 voprf_pst1_blind,
88 voprf_pst1_sign,
89 voprf_pst1_unblind,
90 voprf_pst1_read,
91 0, /* has_private_metadata */
92 6, /* max_keys */
93 0, /* has_srr */
94 };
95 return &kMethod;
96 }
97
TRUST_TOKEN_pst_v1_pmb(void)98 const TRUST_TOKEN_METHOD *TRUST_TOKEN_pst_v1_pmb(void) {
99 static const TRUST_TOKEN_METHOD kMethod = {
100 pmbtoken_pst1_generate_key,
101 pmbtoken_pst1_derive_key_from_secret,
102 pmbtoken_pst1_client_key_from_bytes,
103 pmbtoken_pst1_issuer_key_from_bytes,
104 pmbtoken_pst1_blind,
105 pmbtoken_pst1_sign,
106 pmbtoken_pst1_unblind,
107 pmbtoken_pst1_read,
108 1, /* has_private_metadata */
109 3, /* max_keys */
110 0, /* has_srr */
111 };
112 return &kMethod;
113 }
114
115
TRUST_TOKEN_PRETOKEN_free(TRUST_TOKEN_PRETOKEN * pretoken)116 void TRUST_TOKEN_PRETOKEN_free(TRUST_TOKEN_PRETOKEN *pretoken) {
117 OPENSSL_free(pretoken);
118 }
119
TRUST_TOKEN_new(const uint8_t * data,size_t len)120 TRUST_TOKEN *TRUST_TOKEN_new(const uint8_t *data, size_t len) {
121 TRUST_TOKEN *ret =
122 reinterpret_cast<TRUST_TOKEN *>(OPENSSL_zalloc(sizeof(TRUST_TOKEN)));
123 if (ret == NULL) {
124 return NULL;
125 }
126 ret->data = reinterpret_cast<uint8_t *>(OPENSSL_memdup(data, len));
127 if (len != 0 && ret->data == NULL) {
128 OPENSSL_free(ret);
129 return NULL;
130 }
131 ret->len = len;
132 return ret;
133 }
134
TRUST_TOKEN_free(TRUST_TOKEN * token)135 void TRUST_TOKEN_free(TRUST_TOKEN *token) {
136 if (token == NULL) {
137 return;
138 }
139 OPENSSL_free(token->data);
140 OPENSSL_free(token);
141 }
142
TRUST_TOKEN_generate_key(const TRUST_TOKEN_METHOD * method,uint8_t * out_priv_key,size_t * out_priv_key_len,size_t max_priv_key_len,uint8_t * out_pub_key,size_t * out_pub_key_len,size_t max_pub_key_len,uint32_t id)143 int TRUST_TOKEN_generate_key(const TRUST_TOKEN_METHOD *method,
144 uint8_t *out_priv_key, size_t *out_priv_key_len,
145 size_t max_priv_key_len, uint8_t *out_pub_key,
146 size_t *out_pub_key_len, size_t max_pub_key_len,
147 uint32_t id) {
148 // Prepend the key ID in front of the PMBTokens format.
149 CBB priv_cbb, pub_cbb;
150 CBB_init_fixed(&priv_cbb, out_priv_key, max_priv_key_len);
151 CBB_init_fixed(&pub_cbb, out_pub_key, max_pub_key_len);
152 if (!CBB_add_u32(&priv_cbb, id) || //
153 !CBB_add_u32(&pub_cbb, id)) {
154 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL);
155 return 0;
156 }
157
158 if (!method->generate_key(&priv_cbb, &pub_cbb)) {
159 return 0;
160 }
161
162 if (!CBB_finish(&priv_cbb, NULL, out_priv_key_len) ||
163 !CBB_finish(&pub_cbb, NULL, out_pub_key_len)) {
164 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL);
165 return 0;
166 }
167
168 return 1;
169 }
170
TRUST_TOKEN_derive_key_from_secret(const TRUST_TOKEN_METHOD * method,uint8_t * out_priv_key,size_t * out_priv_key_len,size_t max_priv_key_len,uint8_t * out_pub_key,size_t * out_pub_key_len,size_t max_pub_key_len,uint32_t id,const uint8_t * secret,size_t secret_len)171 int TRUST_TOKEN_derive_key_from_secret(
172 const TRUST_TOKEN_METHOD *method, uint8_t *out_priv_key,
173 size_t *out_priv_key_len, size_t max_priv_key_len, uint8_t *out_pub_key,
174 size_t *out_pub_key_len, size_t max_pub_key_len, uint32_t id,
175 const uint8_t *secret, size_t secret_len) {
176 // Prepend the key ID in front of the PMBTokens format.
177 CBB priv_cbb, pub_cbb;
178 CBB_init_fixed(&priv_cbb, out_priv_key, max_priv_key_len);
179 CBB_init_fixed(&pub_cbb, out_pub_key, max_pub_key_len);
180 if (!CBB_add_u32(&priv_cbb, id) || //
181 !CBB_add_u32(&pub_cbb, id)) {
182 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL);
183 return 0;
184 }
185
186 if (!method->derive_key_from_secret(&priv_cbb, &pub_cbb, secret,
187 secret_len)) {
188 return 0;
189 }
190
191 if (!CBB_finish(&priv_cbb, NULL, out_priv_key_len) ||
192 !CBB_finish(&pub_cbb, NULL, out_pub_key_len)) {
193 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL);
194 return 0;
195 }
196
197 return 1;
198 }
199
TRUST_TOKEN_CLIENT_new(const TRUST_TOKEN_METHOD * method,size_t max_batchsize)200 TRUST_TOKEN_CLIENT *TRUST_TOKEN_CLIENT_new(const TRUST_TOKEN_METHOD *method,
201 size_t max_batchsize) {
202 if (max_batchsize > 0xffff) {
203 // The protocol supports only two-byte token counts.
204 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
205 return NULL;
206 }
207
208 TRUST_TOKEN_CLIENT *ret = reinterpret_cast<TRUST_TOKEN_CLIENT *>(
209 OPENSSL_zalloc(sizeof(TRUST_TOKEN_CLIENT)));
210 if (ret == NULL) {
211 return NULL;
212 }
213 ret->method = method;
214 ret->max_batchsize = (uint16_t)max_batchsize;
215 return ret;
216 }
217
TRUST_TOKEN_CLIENT_free(TRUST_TOKEN_CLIENT * ctx)218 void TRUST_TOKEN_CLIENT_free(TRUST_TOKEN_CLIENT *ctx) {
219 if (ctx == NULL) {
220 return;
221 }
222 EVP_PKEY_free(ctx->srr_key);
223 sk_TRUST_TOKEN_PRETOKEN_pop_free(ctx->pretokens, TRUST_TOKEN_PRETOKEN_free);
224 OPENSSL_free(ctx);
225 }
226
TRUST_TOKEN_CLIENT_add_key(TRUST_TOKEN_CLIENT * ctx,size_t * out_key_index,const uint8_t * key,size_t key_len)227 int TRUST_TOKEN_CLIENT_add_key(TRUST_TOKEN_CLIENT *ctx, size_t *out_key_index,
228 const uint8_t *key, size_t key_len) {
229 if (ctx->num_keys == OPENSSL_ARRAY_SIZE(ctx->keys) ||
230 ctx->num_keys >= ctx->method->max_keys) {
231 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_TOO_MANY_KEYS);
232 return 0;
233 }
234
235 struct trust_token_client_key_st *key_s = &ctx->keys[ctx->num_keys];
236 CBS cbs;
237 CBS_init(&cbs, key, key_len);
238 uint32_t key_id;
239 if (!CBS_get_u32(&cbs, &key_id) ||
240 !ctx->method->client_key_from_bytes(&key_s->key, CBS_data(&cbs),
241 CBS_len(&cbs))) {
242 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
243 return 0;
244 }
245 key_s->id = key_id;
246 *out_key_index = ctx->num_keys;
247 ctx->num_keys += 1;
248 return 1;
249 }
250
TRUST_TOKEN_CLIENT_set_srr_key(TRUST_TOKEN_CLIENT * ctx,EVP_PKEY * key)251 int TRUST_TOKEN_CLIENT_set_srr_key(TRUST_TOKEN_CLIENT *ctx, EVP_PKEY *key) {
252 if (!ctx->method->has_srr) {
253 return 1;
254 }
255 EVP_PKEY_free(ctx->srr_key);
256 EVP_PKEY_up_ref(key);
257 ctx->srr_key = key;
258 return 1;
259 }
260
trust_token_client_begin_issuance_impl(TRUST_TOKEN_CLIENT * ctx,uint8_t ** out,size_t * out_len,size_t count,int include_message,const uint8_t * msg,size_t msg_len)261 static int trust_token_client_begin_issuance_impl(
262 TRUST_TOKEN_CLIENT *ctx, uint8_t **out, size_t *out_len, size_t count,
263 int include_message, const uint8_t *msg, size_t msg_len) {
264 if (count > ctx->max_batchsize) {
265 count = ctx->max_batchsize;
266 }
267
268 int ret = 0;
269 CBB request;
270 STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens = NULL;
271 if (!CBB_init(&request, 0) || !CBB_add_u16(&request, count)) {
272 goto err;
273 }
274
275 pretokens =
276 ctx->method->blind(&request, count, include_message, msg, msg_len);
277 if (pretokens == NULL) {
278 goto err;
279 }
280
281 if (!CBB_finish(&request, out, out_len)) {
282 goto err;
283 }
284
285 sk_TRUST_TOKEN_PRETOKEN_pop_free(ctx->pretokens, TRUST_TOKEN_PRETOKEN_free);
286 ctx->pretokens = pretokens;
287 pretokens = NULL;
288 ret = 1;
289
290 err:
291 CBB_cleanup(&request);
292 sk_TRUST_TOKEN_PRETOKEN_pop_free(pretokens, TRUST_TOKEN_PRETOKEN_free);
293 return ret;
294 }
295
TRUST_TOKEN_CLIENT_begin_issuance(TRUST_TOKEN_CLIENT * ctx,uint8_t ** out,size_t * out_len,size_t count)296 int TRUST_TOKEN_CLIENT_begin_issuance(TRUST_TOKEN_CLIENT *ctx, uint8_t **out,
297 size_t *out_len, size_t count) {
298 return trust_token_client_begin_issuance_impl(ctx, out, out_len, count,
299 /*include_message=*/0, NULL, 0);
300 }
301
TRUST_TOKEN_CLIENT_begin_issuance_over_message(TRUST_TOKEN_CLIENT * ctx,uint8_t ** out,size_t * out_len,size_t count,const uint8_t * msg,size_t msg_len)302 int TRUST_TOKEN_CLIENT_begin_issuance_over_message(
303 TRUST_TOKEN_CLIENT *ctx, uint8_t **out, size_t *out_len, size_t count,
304 const uint8_t *msg, size_t msg_len) {
305 return trust_token_client_begin_issuance_impl(
306 ctx, out, out_len, count, /*include_message=*/1, msg, msg_len);
307 }
308
309
STACK_OF(TRUST_TOKEN)310 STACK_OF(TRUST_TOKEN) *TRUST_TOKEN_CLIENT_finish_issuance(
311 TRUST_TOKEN_CLIENT *ctx, size_t *out_key_index, const uint8_t *response,
312 size_t response_len) {
313 CBS in;
314 CBS_init(&in, response, response_len);
315 uint16_t count;
316 uint32_t key_id;
317 if (!CBS_get_u16(&in, &count) || !CBS_get_u32(&in, &key_id)) {
318 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
319 return NULL;
320 }
321
322 size_t key_index = 0;
323 const struct trust_token_client_key_st *key = NULL;
324 for (size_t i = 0; i < ctx->num_keys; i++) {
325 if (ctx->keys[i].id == key_id) {
326 key_index = i;
327 key = &ctx->keys[i];
328 break;
329 }
330 }
331
332 if (key == NULL) {
333 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_KEY_ID);
334 return NULL;
335 }
336
337 if (count > sk_TRUST_TOKEN_PRETOKEN_num(ctx->pretokens)) {
338 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
339 return NULL;
340 }
341
342 STACK_OF(TRUST_TOKEN) *tokens =
343 ctx->method->unblind(&key->key, ctx->pretokens, &in, count, key_id);
344 if (tokens == NULL) {
345 return NULL;
346 }
347
348 if (CBS_len(&in) != 0) {
349 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
350 sk_TRUST_TOKEN_pop_free(tokens, TRUST_TOKEN_free);
351 return NULL;
352 }
353
354 sk_TRUST_TOKEN_PRETOKEN_pop_free(ctx->pretokens, TRUST_TOKEN_PRETOKEN_free);
355 ctx->pretokens = NULL;
356
357 *out_key_index = key_index;
358 return tokens;
359 }
360
TRUST_TOKEN_CLIENT_begin_redemption(TRUST_TOKEN_CLIENT * ctx,uint8_t ** out,size_t * out_len,const TRUST_TOKEN * token,const uint8_t * data,size_t data_len,uint64_t time)361 int TRUST_TOKEN_CLIENT_begin_redemption(TRUST_TOKEN_CLIENT *ctx, uint8_t **out,
362 size_t *out_len,
363 const TRUST_TOKEN *token,
364 const uint8_t *data, size_t data_len,
365 uint64_t time) {
366 CBB request, token_inner, inner;
367 if (!CBB_init(&request, 0) ||
368 !CBB_add_u16_length_prefixed(&request, &token_inner) ||
369 !CBB_add_bytes(&token_inner, token->data, token->len) ||
370 !CBB_add_u16_length_prefixed(&request, &inner) ||
371 !CBB_add_bytes(&inner, data, data_len) ||
372 (ctx->method->has_srr && !CBB_add_u64(&request, time)) ||
373 !CBB_finish(&request, out, out_len)) {
374 CBB_cleanup(&request);
375 return 0;
376 }
377 return 1;
378 }
379
TRUST_TOKEN_CLIENT_finish_redemption(TRUST_TOKEN_CLIENT * ctx,uint8_t ** out_rr,size_t * out_rr_len,uint8_t ** out_sig,size_t * out_sig_len,const uint8_t * response,size_t response_len)380 int TRUST_TOKEN_CLIENT_finish_redemption(TRUST_TOKEN_CLIENT *ctx,
381 uint8_t **out_rr, size_t *out_rr_len,
382 uint8_t **out_sig, size_t *out_sig_len,
383 const uint8_t *response,
384 size_t response_len) {
385 CBS in, srr, sig;
386 CBS_init(&in, response, response_len);
387 if (!ctx->method->has_srr) {
388 if (!CBS_stow(&in, out_rr, out_rr_len)) {
389 return 0;
390 }
391
392 *out_sig = NULL;
393 *out_sig_len = 0;
394 return 1;
395 }
396
397 if (!CBS_get_u16_length_prefixed(&in, &srr) ||
398 !CBS_get_u16_length_prefixed(&in, &sig) || CBS_len(&in) != 0) {
399 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR);
400 return 0;
401 }
402
403 if (ctx->srr_key == NULL) {
404 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_NO_SRR_KEY_CONFIGURED);
405 return 0;
406 }
407
408 EVP_MD_CTX md_ctx;
409 EVP_MD_CTX_init(&md_ctx);
410 int sig_ok = EVP_DigestVerifyInit(&md_ctx, NULL, NULL, NULL, ctx->srr_key) &&
411 EVP_DigestVerify(&md_ctx, CBS_data(&sig), CBS_len(&sig),
412 CBS_data(&srr), CBS_len(&srr));
413 EVP_MD_CTX_cleanup(&md_ctx);
414
415 if (!sig_ok) {
416 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_SRR_SIGNATURE_ERROR);
417 return 0;
418 }
419
420 uint8_t *srr_buf = NULL, *sig_buf = NULL;
421 size_t srr_len, sig_len;
422 if (!CBS_stow(&srr, &srr_buf, &srr_len) ||
423 !CBS_stow(&sig, &sig_buf, &sig_len)) {
424 OPENSSL_free(srr_buf);
425 OPENSSL_free(sig_buf);
426 return 0;
427 }
428
429 *out_rr = srr_buf;
430 *out_rr_len = srr_len;
431 *out_sig = sig_buf;
432 *out_sig_len = sig_len;
433 return 1;
434 }
435
TRUST_TOKEN_ISSUER_new(const TRUST_TOKEN_METHOD * method,size_t max_batchsize)436 TRUST_TOKEN_ISSUER *TRUST_TOKEN_ISSUER_new(const TRUST_TOKEN_METHOD *method,
437 size_t max_batchsize) {
438 if (max_batchsize > 0xffff) {
439 // The protocol supports only two-byte token counts.
440 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
441 return NULL;
442 }
443
444 TRUST_TOKEN_ISSUER *ret = reinterpret_cast<TRUST_TOKEN_ISSUER *>(
445 OPENSSL_zalloc(sizeof(TRUST_TOKEN_ISSUER)));
446 if (ret == NULL) {
447 return NULL;
448 }
449 ret->method = method;
450 ret->max_batchsize = (uint16_t)max_batchsize;
451 return ret;
452 }
453
TRUST_TOKEN_ISSUER_free(TRUST_TOKEN_ISSUER * ctx)454 void TRUST_TOKEN_ISSUER_free(TRUST_TOKEN_ISSUER *ctx) {
455 if (ctx == NULL) {
456 return;
457 }
458 EVP_PKEY_free(ctx->srr_key);
459 OPENSSL_free(ctx->metadata_key);
460 OPENSSL_free(ctx);
461 }
462
TRUST_TOKEN_ISSUER_add_key(TRUST_TOKEN_ISSUER * ctx,const uint8_t * key,size_t key_len)463 int TRUST_TOKEN_ISSUER_add_key(TRUST_TOKEN_ISSUER *ctx, const uint8_t *key,
464 size_t key_len) {
465 if (ctx->num_keys == OPENSSL_ARRAY_SIZE(ctx->keys) ||
466 ctx->num_keys >= ctx->method->max_keys) {
467 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_TOO_MANY_KEYS);
468 return 0;
469 }
470
471 struct trust_token_issuer_key_st *key_s = &ctx->keys[ctx->num_keys];
472 CBS cbs;
473 CBS_init(&cbs, key, key_len);
474 uint32_t key_id;
475 if (!CBS_get_u32(&cbs, &key_id) ||
476 !ctx->method->issuer_key_from_bytes(&key_s->key, CBS_data(&cbs),
477 CBS_len(&cbs))) {
478 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
479 return 0;
480 }
481
482 key_s->id = key_id;
483 ctx->num_keys += 1;
484 return 1;
485 }
486
TRUST_TOKEN_ISSUER_set_srr_key(TRUST_TOKEN_ISSUER * ctx,EVP_PKEY * key)487 int TRUST_TOKEN_ISSUER_set_srr_key(TRUST_TOKEN_ISSUER *ctx, EVP_PKEY *key) {
488 EVP_PKEY_free(ctx->srr_key);
489 EVP_PKEY_up_ref(key);
490 ctx->srr_key = key;
491 return 1;
492 }
493
TRUST_TOKEN_ISSUER_set_metadata_key(TRUST_TOKEN_ISSUER * ctx,const uint8_t * key,size_t len)494 int TRUST_TOKEN_ISSUER_set_metadata_key(TRUST_TOKEN_ISSUER *ctx,
495 const uint8_t *key, size_t len) {
496 if (len < 32) {
497 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_METADATA_KEY);
498 }
499 OPENSSL_free(ctx->metadata_key);
500 ctx->metadata_key_len = 0;
501 ctx->metadata_key = reinterpret_cast<uint8_t *>(OPENSSL_memdup(key, len));
502 if (ctx->metadata_key == NULL) {
503 return 0;
504 }
505 ctx->metadata_key_len = len;
506 return 1;
507 }
508
trust_token_issuer_get_key(const TRUST_TOKEN_ISSUER * ctx,uint32_t key_id)509 static const struct trust_token_issuer_key_st *trust_token_issuer_get_key(
510 const TRUST_TOKEN_ISSUER *ctx, uint32_t key_id) {
511 for (size_t i = 0; i < ctx->num_keys; i++) {
512 if (ctx->keys[i].id == key_id) {
513 return &ctx->keys[i];
514 }
515 }
516 return NULL;
517 }
518
TRUST_TOKEN_ISSUER_issue(const TRUST_TOKEN_ISSUER * ctx,uint8_t ** out,size_t * out_len,size_t * out_tokens_issued,const uint8_t * request,size_t request_len,uint32_t public_metadata,uint8_t private_metadata,size_t max_issuance)519 int TRUST_TOKEN_ISSUER_issue(const TRUST_TOKEN_ISSUER *ctx, uint8_t **out,
520 size_t *out_len, size_t *out_tokens_issued,
521 const uint8_t *request, size_t request_len,
522 uint32_t public_metadata, uint8_t private_metadata,
523 size_t max_issuance) {
524 if (max_issuance > ctx->max_batchsize) {
525 max_issuance = ctx->max_batchsize;
526 }
527
528 const struct trust_token_issuer_key_st *key =
529 trust_token_issuer_get_key(ctx, public_metadata);
530 if (key == NULL || private_metadata > 1 ||
531 (!ctx->method->has_private_metadata && private_metadata != 0)) {
532 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_METADATA);
533 return 0;
534 }
535
536 CBS in;
537 uint16_t num_requested;
538 CBS_init(&in, request, request_len);
539 if (!CBS_get_u16(&in, &num_requested)) {
540 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
541 return 0;
542 }
543
544 size_t num_to_issue = num_requested;
545 if (num_to_issue > max_issuance) {
546 num_to_issue = max_issuance;
547 }
548
549 int ret = 0;
550 CBB response;
551 if (!CBB_init(&response, 0) || !CBB_add_u16(&response, num_to_issue) ||
552 !CBB_add_u32(&response, public_metadata)) {
553 goto err;
554 }
555
556 if (!ctx->method->sign(&key->key, &response, &in, num_requested, num_to_issue,
557 private_metadata)) {
558 goto err;
559 }
560
561 if (CBS_len(&in) != 0) {
562 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
563 goto err;
564 }
565
566 if (!CBB_finish(&response, out, out_len)) {
567 goto err;
568 }
569
570 *out_tokens_issued = num_to_issue;
571 ret = 1;
572
573 err:
574 CBB_cleanup(&response);
575 return ret;
576 }
577
trust_token_issuer_redeem_impl(const TRUST_TOKEN_ISSUER * ctx,uint32_t * out_public,uint8_t * out_private,TRUST_TOKEN ** out_token,uint8_t ** out_client_data,size_t * out_client_data_len,const uint8_t * request,size_t request_len,int include_message,const uint8_t * msg,size_t msg_len)578 static int trust_token_issuer_redeem_impl(
579 const TRUST_TOKEN_ISSUER *ctx, uint32_t *out_public, uint8_t *out_private,
580 TRUST_TOKEN **out_token, uint8_t **out_client_data,
581 size_t *out_client_data_len, const uint8_t *request, size_t request_len,
582 int include_message, const uint8_t *msg, size_t msg_len) {
583 CBS request_cbs, token_cbs;
584 CBS_init(&request_cbs, request, request_len);
585 if (!CBS_get_u16_length_prefixed(&request_cbs, &token_cbs)) {
586 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR);
587 return 0;
588 }
589
590 uint32_t public_metadata = 0;
591 uint8_t private_metadata = 0;
592
593 // Parse the token. If there is an error, treat it as an invalid token.
594 if (!CBS_get_u32(&token_cbs, &public_metadata)) {
595 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN);
596 return 0;
597 }
598
599 const struct trust_token_issuer_key_st *key =
600 trust_token_issuer_get_key(ctx, public_metadata);
601 uint8_t nonce[TRUST_TOKEN_NONCE_SIZE];
602 if (key == NULL ||
603 !ctx->method->read(&key->key, nonce, &private_metadata,
604 CBS_data(&token_cbs), CBS_len(&token_cbs),
605 include_message, msg, msg_len)) {
606 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN);
607 return 0;
608 }
609
610 CBS client_data;
611 if (!CBS_get_u16_length_prefixed(&request_cbs, &client_data) ||
612 (ctx->method->has_srr && !CBS_skip(&request_cbs, 8)) ||
613 CBS_len(&request_cbs) != 0) {
614 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR);
615 return 0;
616 }
617
618 uint8_t *client_data_buf = NULL;
619 size_t client_data_len = 0;
620 TRUST_TOKEN *token;
621 if (!CBS_stow(&client_data, &client_data_buf, &client_data_len)) {
622 goto err;
623 }
624
625 token = TRUST_TOKEN_new(nonce, TRUST_TOKEN_NONCE_SIZE);
626 if (token == NULL) {
627 goto err;
628 }
629 *out_public = public_metadata;
630 *out_private = private_metadata;
631 *out_token = token;
632 *out_client_data = client_data_buf;
633 *out_client_data_len = client_data_len;
634
635 return 1;
636
637 err:
638 OPENSSL_free(client_data_buf);
639 return 0;
640 }
641
642
TRUST_TOKEN_ISSUER_redeem(const TRUST_TOKEN_ISSUER * ctx,uint32_t * out_public,uint8_t * out_private,TRUST_TOKEN ** out_token,uint8_t ** out_client_data,size_t * out_client_data_len,const uint8_t * request,size_t request_len)643 int TRUST_TOKEN_ISSUER_redeem(const TRUST_TOKEN_ISSUER *ctx,
644 uint32_t *out_public, uint8_t *out_private,
645 TRUST_TOKEN **out_token,
646 uint8_t **out_client_data,
647 size_t *out_client_data_len,
648 const uint8_t *request, size_t request_len) {
649 return trust_token_issuer_redeem_impl(ctx, out_public, out_private, out_token,
650 out_client_data, out_client_data_len,
651 request, request_len, 0, NULL, 0);
652 }
653
TRUST_TOKEN_ISSUER_redeem_over_message(const TRUST_TOKEN_ISSUER * ctx,uint32_t * out_public,uint8_t * out_private,TRUST_TOKEN ** out_token,uint8_t ** out_client_data,size_t * out_client_data_len,const uint8_t * request,size_t request_len,const uint8_t * msg,size_t msg_len)654 int TRUST_TOKEN_ISSUER_redeem_over_message(
655 const TRUST_TOKEN_ISSUER *ctx, uint32_t *out_public, uint8_t *out_private,
656 TRUST_TOKEN **out_token, uint8_t **out_client_data,
657 size_t *out_client_data_len, const uint8_t *request, size_t request_len,
658 const uint8_t *msg, size_t msg_len) {
659 return trust_token_issuer_redeem_impl(ctx, out_public, out_private, out_token,
660 out_client_data, out_client_data_len,
661 request, request_len, 1, msg, msg_len);
662 }
663
get_metadata_obfuscator(const uint8_t * key,size_t key_len,const uint8_t * client_data,size_t client_data_len)664 static uint8_t get_metadata_obfuscator(const uint8_t *key, size_t key_len,
665 const uint8_t *client_data,
666 size_t client_data_len) {
667 uint8_t metadata_obfuscator[SHA256_DIGEST_LENGTH];
668 SHA256_CTX sha_ctx;
669 SHA256_Init(&sha_ctx);
670 SHA256_Update(&sha_ctx, key, key_len);
671 SHA256_Update(&sha_ctx, client_data, client_data_len);
672 SHA256_Final(metadata_obfuscator, &sha_ctx);
673 return metadata_obfuscator[0] >> 7;
674 }
675
TRUST_TOKEN_decode_private_metadata(const TRUST_TOKEN_METHOD * method,uint8_t * out_value,const uint8_t * key,size_t key_len,const uint8_t * nonce,size_t nonce_len,uint8_t encrypted_bit)676 int TRUST_TOKEN_decode_private_metadata(const TRUST_TOKEN_METHOD *method,
677 uint8_t *out_value, const uint8_t *key,
678 size_t key_len, const uint8_t *nonce,
679 size_t nonce_len,
680 uint8_t encrypted_bit) {
681 uint8_t metadata_obfuscator =
682 get_metadata_obfuscator(key, key_len, nonce, nonce_len);
683 *out_value = encrypted_bit ^ metadata_obfuscator;
684 return 1;
685 }
686