1 /* Copyright (c) 2019, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15 #include <openssl/bytestring.h>
16 #include <openssl/err.h>
17 #include <openssl/evp.h>
18 #include <openssl/mem.h>
19 #include <openssl/sha.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/master/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 = OPENSSL_zalloc(sizeof(TRUST_TOKEN));
122 if (ret == NULL) {
123 return NULL;
124 }
125 ret->data = OPENSSL_memdup(data, len);
126 if (len != 0 && ret->data == NULL) {
127 OPENSSL_free(ret);
128 return NULL;
129 }
130 ret->len = len;
131 return ret;
132 }
133
TRUST_TOKEN_free(TRUST_TOKEN * token)134 void TRUST_TOKEN_free(TRUST_TOKEN *token) {
135 if (token == NULL) {
136 return;
137 }
138 OPENSSL_free(token->data);
139 OPENSSL_free(token);
140 }
141
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)142 int TRUST_TOKEN_generate_key(const TRUST_TOKEN_METHOD *method,
143 uint8_t *out_priv_key, size_t *out_priv_key_len,
144 size_t max_priv_key_len, uint8_t *out_pub_key,
145 size_t *out_pub_key_len, size_t max_pub_key_len,
146 uint32_t id) {
147 // Prepend the key ID in front of the PMBTokens format.
148 CBB priv_cbb, pub_cbb;
149 CBB_init_fixed(&priv_cbb, out_priv_key, max_priv_key_len);
150 CBB_init_fixed(&pub_cbb, out_pub_key, max_pub_key_len);
151 if (!CBB_add_u32(&priv_cbb, id) || //
152 !CBB_add_u32(&pub_cbb, id)) {
153 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL);
154 return 0;
155 }
156
157 if (!method->generate_key(&priv_cbb, &pub_cbb)) {
158 return 0;
159 }
160
161 if (!CBB_finish(&priv_cbb, NULL, out_priv_key_len) ||
162 !CBB_finish(&pub_cbb, NULL, out_pub_key_len)) {
163 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL);
164 return 0;
165 }
166
167 return 1;
168 }
169
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)170 int TRUST_TOKEN_derive_key_from_secret(
171 const TRUST_TOKEN_METHOD *method, uint8_t *out_priv_key,
172 size_t *out_priv_key_len, size_t max_priv_key_len, uint8_t *out_pub_key,
173 size_t *out_pub_key_len, size_t max_pub_key_len, uint32_t id,
174 const uint8_t *secret, size_t secret_len) {
175 // Prepend the key ID in front of the PMBTokens format.
176 CBB priv_cbb, pub_cbb;
177 CBB_init_fixed(&priv_cbb, out_priv_key, max_priv_key_len);
178 CBB_init_fixed(&pub_cbb, out_pub_key, max_pub_key_len);
179 if (!CBB_add_u32(&priv_cbb, id) || //
180 !CBB_add_u32(&pub_cbb, id)) {
181 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL);
182 return 0;
183 }
184
185 if (!method->derive_key_from_secret(&priv_cbb, &pub_cbb, secret,
186 secret_len)) {
187 return 0;
188 }
189
190 if (!CBB_finish(&priv_cbb, NULL, out_priv_key_len) ||
191 !CBB_finish(&pub_cbb, NULL, out_pub_key_len)) {
192 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL);
193 return 0;
194 }
195
196 return 1;
197 }
198
TRUST_TOKEN_CLIENT_new(const TRUST_TOKEN_METHOD * method,size_t max_batchsize)199 TRUST_TOKEN_CLIENT *TRUST_TOKEN_CLIENT_new(const TRUST_TOKEN_METHOD *method,
200 size_t max_batchsize) {
201 if (max_batchsize > 0xffff) {
202 // The protocol supports only two-byte token counts.
203 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
204 return NULL;
205 }
206
207 TRUST_TOKEN_CLIENT *ret = OPENSSL_zalloc(sizeof(TRUST_TOKEN_CLIENT));
208 if (ret == NULL) {
209 return NULL;
210 }
211 ret->method = method;
212 ret->max_batchsize = (uint16_t)max_batchsize;
213 return ret;
214 }
215
TRUST_TOKEN_CLIENT_free(TRUST_TOKEN_CLIENT * ctx)216 void TRUST_TOKEN_CLIENT_free(TRUST_TOKEN_CLIENT *ctx) {
217 if (ctx == NULL) {
218 return;
219 }
220 EVP_PKEY_free(ctx->srr_key);
221 sk_TRUST_TOKEN_PRETOKEN_pop_free(ctx->pretokens, TRUST_TOKEN_PRETOKEN_free);
222 OPENSSL_free(ctx);
223 }
224
TRUST_TOKEN_CLIENT_add_key(TRUST_TOKEN_CLIENT * ctx,size_t * out_key_index,const uint8_t * key,size_t key_len)225 int TRUST_TOKEN_CLIENT_add_key(TRUST_TOKEN_CLIENT *ctx, size_t *out_key_index,
226 const uint8_t *key, size_t key_len) {
227 if (ctx->num_keys == OPENSSL_ARRAY_SIZE(ctx->keys) ||
228 ctx->num_keys >= ctx->method->max_keys) {
229 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_TOO_MANY_KEYS);
230 return 0;
231 }
232
233 struct trust_token_client_key_st *key_s = &ctx->keys[ctx->num_keys];
234 CBS cbs;
235 CBS_init(&cbs, key, key_len);
236 uint32_t key_id;
237 if (!CBS_get_u32(&cbs, &key_id) ||
238 !ctx->method->client_key_from_bytes(&key_s->key, CBS_data(&cbs),
239 CBS_len(&cbs))) {
240 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
241 return 0;
242 }
243 key_s->id = key_id;
244 *out_key_index = ctx->num_keys;
245 ctx->num_keys += 1;
246 return 1;
247 }
248
TRUST_TOKEN_CLIENT_set_srr_key(TRUST_TOKEN_CLIENT * ctx,EVP_PKEY * key)249 int TRUST_TOKEN_CLIENT_set_srr_key(TRUST_TOKEN_CLIENT *ctx, EVP_PKEY *key) {
250 if (!ctx->method->has_srr) {
251 return 1;
252 }
253 EVP_PKEY_free(ctx->srr_key);
254 EVP_PKEY_up_ref(key);
255 ctx->srr_key = key;
256 return 1;
257 }
258
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)259 static int trust_token_client_begin_issuance_impl(
260 TRUST_TOKEN_CLIENT *ctx, uint8_t **out, size_t *out_len, size_t count,
261 int include_message, const uint8_t *msg, size_t msg_len) {
262 if (count > ctx->max_batchsize) {
263 count = ctx->max_batchsize;
264 }
265
266 int ret = 0;
267 CBB request;
268 STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens = NULL;
269 if (!CBB_init(&request, 0) ||
270 !CBB_add_u16(&request, count)) {
271 goto err;
272 }
273
274 pretokens =
275 ctx->method->blind(&request, count, include_message, msg, msg_len);
276 if (pretokens == NULL) {
277 goto err;
278 }
279
280 if (!CBB_finish(&request, out, out_len)) {
281 goto err;
282 }
283
284 sk_TRUST_TOKEN_PRETOKEN_pop_free(ctx->pretokens, TRUST_TOKEN_PRETOKEN_free);
285 ctx->pretokens = pretokens;
286 pretokens = NULL;
287 ret = 1;
288
289 err:
290 CBB_cleanup(&request);
291 sk_TRUST_TOKEN_PRETOKEN_pop_free(pretokens, TRUST_TOKEN_PRETOKEN_free);
292 return ret;
293 }
294
TRUST_TOKEN_CLIENT_begin_issuance(TRUST_TOKEN_CLIENT * ctx,uint8_t ** out,size_t * out_len,size_t count)295 int TRUST_TOKEN_CLIENT_begin_issuance(TRUST_TOKEN_CLIENT *ctx, uint8_t **out,
296 size_t *out_len, size_t count) {
297 return trust_token_client_begin_issuance_impl(ctx, out, out_len, count,
298 /*include_message=*/0, NULL, 0);
299 }
300
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)301 int TRUST_TOKEN_CLIENT_begin_issuance_over_message(
302 TRUST_TOKEN_CLIENT *ctx, uint8_t **out, size_t *out_len, size_t count,
303 const uint8_t *msg, size_t msg_len) {
304 return trust_token_client_begin_issuance_impl(
305 ctx, out, out_len, count, /*include_message=*/1, msg, msg_len);
306 }
307
308
STACK_OF(TRUST_TOKEN)309 STACK_OF(TRUST_TOKEN) *
310 TRUST_TOKEN_CLIENT_finish_issuance(TRUST_TOKEN_CLIENT *ctx,
311 size_t *out_key_index,
312 const uint8_t *response,
313 size_t response_len) {
314 CBS in;
315 CBS_init(&in, response, response_len);
316 uint16_t count;
317 uint32_t key_id;
318 if (!CBS_get_u16(&in, &count) ||
319 !CBS_get_u32(&in, &key_id)) {
320 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
321 return NULL;
322 }
323
324 size_t key_index = 0;
325 const struct trust_token_client_key_st *key = NULL;
326 for (size_t i = 0; i < ctx->num_keys; i++) {
327 if (ctx->keys[i].id == key_id) {
328 key_index = i;
329 key = &ctx->keys[i];
330 break;
331 }
332 }
333
334 if (key == NULL) {
335 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_KEY_ID);
336 return NULL;
337 }
338
339 if (count > sk_TRUST_TOKEN_PRETOKEN_num(ctx->pretokens)) {
340 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
341 return NULL;
342 }
343
344 STACK_OF(TRUST_TOKEN) *tokens =
345 ctx->method->unblind(&key->key, ctx->pretokens, &in, count, key_id);
346 if (tokens == NULL) {
347 return NULL;
348 }
349
350 if (CBS_len(&in) != 0) {
351 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
352 sk_TRUST_TOKEN_pop_free(tokens, TRUST_TOKEN_free);
353 return NULL;
354 }
355
356 sk_TRUST_TOKEN_PRETOKEN_pop_free(ctx->pretokens, TRUST_TOKEN_PRETOKEN_free);
357 ctx->pretokens = NULL;
358
359 *out_key_index = key_index;
360 return tokens;
361 }
362
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)363 int TRUST_TOKEN_CLIENT_begin_redemption(TRUST_TOKEN_CLIENT *ctx, uint8_t **out,
364 size_t *out_len,
365 const TRUST_TOKEN *token,
366 const uint8_t *data, size_t data_len,
367 uint64_t time) {
368 CBB request, token_inner, inner;
369 if (!CBB_init(&request, 0) ||
370 !CBB_add_u16_length_prefixed(&request, &token_inner) ||
371 !CBB_add_bytes(&token_inner, token->data, token->len) ||
372 !CBB_add_u16_length_prefixed(&request, &inner) ||
373 !CBB_add_bytes(&inner, data, data_len) ||
374 (ctx->method->has_srr && !CBB_add_u64(&request, time)) ||
375 !CBB_finish(&request, out, out_len)) {
376 CBB_cleanup(&request);
377 return 0;
378 }
379 return 1;
380 }
381
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)382 int TRUST_TOKEN_CLIENT_finish_redemption(TRUST_TOKEN_CLIENT *ctx,
383 uint8_t **out_rr, size_t *out_rr_len,
384 uint8_t **out_sig, size_t *out_sig_len,
385 const uint8_t *response,
386 size_t response_len) {
387 CBS in, srr, sig;
388 CBS_init(&in, response, response_len);
389 if (!ctx->method->has_srr) {
390 if (!CBS_stow(&in, out_rr, out_rr_len)) {
391 return 0;
392 }
393
394 *out_sig = NULL;
395 *out_sig_len = 0;
396 return 1;
397 }
398
399 if (!CBS_get_u16_length_prefixed(&in, &srr) ||
400 !CBS_get_u16_length_prefixed(&in, &sig) ||
401 CBS_len(&in) != 0) {
402 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR);
403 return 0;
404 }
405
406 if (ctx->srr_key == NULL) {
407 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_NO_SRR_KEY_CONFIGURED);
408 return 0;
409 }
410
411 EVP_MD_CTX md_ctx;
412 EVP_MD_CTX_init(&md_ctx);
413 int sig_ok = EVP_DigestVerifyInit(&md_ctx, NULL, NULL, NULL, ctx->srr_key) &&
414 EVP_DigestVerify(&md_ctx, CBS_data(&sig), CBS_len(&sig),
415 CBS_data(&srr), CBS_len(&srr));
416 EVP_MD_CTX_cleanup(&md_ctx);
417
418 if (!sig_ok) {
419 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_SRR_SIGNATURE_ERROR);
420 return 0;
421 }
422
423 uint8_t *srr_buf = NULL, *sig_buf = NULL;
424 size_t srr_len, sig_len;
425 if (!CBS_stow(&srr, &srr_buf, &srr_len) ||
426 !CBS_stow(&sig, &sig_buf, &sig_len)) {
427 OPENSSL_free(srr_buf);
428 OPENSSL_free(sig_buf);
429 return 0;
430 }
431
432 *out_rr = srr_buf;
433 *out_rr_len = srr_len;
434 *out_sig = sig_buf;
435 *out_sig_len = sig_len;
436 return 1;
437 }
438
TRUST_TOKEN_ISSUER_new(const TRUST_TOKEN_METHOD * method,size_t max_batchsize)439 TRUST_TOKEN_ISSUER *TRUST_TOKEN_ISSUER_new(const TRUST_TOKEN_METHOD *method,
440 size_t max_batchsize) {
441 if (max_batchsize > 0xffff) {
442 // The protocol supports only two-byte token counts.
443 OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
444 return NULL;
445 }
446
447 TRUST_TOKEN_ISSUER *ret = OPENSSL_zalloc(sizeof(TRUST_TOKEN_ISSUER));
448 if (ret == NULL) {
449 return NULL;
450 }
451 ret->method = method;
452 ret->max_batchsize = (uint16_t)max_batchsize;
453 return ret;
454 }
455
TRUST_TOKEN_ISSUER_free(TRUST_TOKEN_ISSUER * ctx)456 void TRUST_TOKEN_ISSUER_free(TRUST_TOKEN_ISSUER *ctx) {
457 if (ctx == NULL) {
458 return;
459 }
460 EVP_PKEY_free(ctx->srr_key);
461 OPENSSL_free(ctx->metadata_key);
462 OPENSSL_free(ctx);
463 }
464
TRUST_TOKEN_ISSUER_add_key(TRUST_TOKEN_ISSUER * ctx,const uint8_t * key,size_t key_len)465 int TRUST_TOKEN_ISSUER_add_key(TRUST_TOKEN_ISSUER *ctx, const uint8_t *key,
466 size_t key_len) {
467 if (ctx->num_keys == OPENSSL_ARRAY_SIZE(ctx->keys) ||
468 ctx->num_keys >= ctx->method->max_keys) {
469 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_TOO_MANY_KEYS);
470 return 0;
471 }
472
473 struct trust_token_issuer_key_st *key_s = &ctx->keys[ctx->num_keys];
474 CBS cbs;
475 CBS_init(&cbs, key, key_len);
476 uint32_t key_id;
477 if (!CBS_get_u32(&cbs, &key_id) ||
478 !ctx->method->issuer_key_from_bytes(&key_s->key, CBS_data(&cbs),
479 CBS_len(&cbs))) {
480 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
481 return 0;
482 }
483
484 key_s->id = key_id;
485 ctx->num_keys += 1;
486 return 1;
487 }
488
TRUST_TOKEN_ISSUER_set_srr_key(TRUST_TOKEN_ISSUER * ctx,EVP_PKEY * key)489 int TRUST_TOKEN_ISSUER_set_srr_key(TRUST_TOKEN_ISSUER *ctx, EVP_PKEY *key) {
490 EVP_PKEY_free(ctx->srr_key);
491 EVP_PKEY_up_ref(key);
492 ctx->srr_key = key;
493 return 1;
494 }
495
TRUST_TOKEN_ISSUER_set_metadata_key(TRUST_TOKEN_ISSUER * ctx,const uint8_t * key,size_t len)496 int TRUST_TOKEN_ISSUER_set_metadata_key(TRUST_TOKEN_ISSUER *ctx,
497 const uint8_t *key, size_t len) {
498 if (len < 32) {
499 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_METADATA_KEY);
500 }
501 OPENSSL_free(ctx->metadata_key);
502 ctx->metadata_key_len = 0;
503 ctx->metadata_key = OPENSSL_memdup(key, len);
504 if (ctx->metadata_key == NULL) {
505 return 0;
506 }
507 ctx->metadata_key_len = len;
508 return 1;
509 }
510
trust_token_issuer_get_key(const TRUST_TOKEN_ISSUER * ctx,uint32_t key_id)511 static const struct trust_token_issuer_key_st *trust_token_issuer_get_key(
512 const TRUST_TOKEN_ISSUER *ctx, uint32_t key_id) {
513 for (size_t i = 0; i < ctx->num_keys; i++) {
514 if (ctx->keys[i].id == key_id) {
515 return &ctx->keys[i];
516 }
517 }
518 return NULL;
519 }
520
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)521 int TRUST_TOKEN_ISSUER_issue(const TRUST_TOKEN_ISSUER *ctx, uint8_t **out,
522 size_t *out_len, size_t *out_tokens_issued,
523 const uint8_t *request, size_t request_len,
524 uint32_t public_metadata, uint8_t private_metadata,
525 size_t max_issuance) {
526 if (max_issuance > ctx->max_batchsize) {
527 max_issuance = ctx->max_batchsize;
528 }
529
530 const struct trust_token_issuer_key_st *key =
531 trust_token_issuer_get_key(ctx, public_metadata);
532 if (key == NULL || private_metadata > 1 ||
533 (!ctx->method->has_private_metadata && private_metadata != 0)) {
534 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_METADATA);
535 return 0;
536 }
537
538 CBS in;
539 uint16_t num_requested;
540 CBS_init(&in, request, request_len);
541 if (!CBS_get_u16(&in, &num_requested)) {
542 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
543 return 0;
544 }
545
546 size_t num_to_issue = num_requested;
547 if (num_to_issue > max_issuance) {
548 num_to_issue = max_issuance;
549 }
550
551 int ret = 0;
552 CBB response;
553 if (!CBB_init(&response, 0) ||
554 !CBB_add_u16(&response, num_to_issue) ||
555 !CBB_add_u32(&response, public_metadata)) {
556 goto err;
557 }
558
559 if (!ctx->method->sign(&key->key, &response, &in, num_requested, num_to_issue,
560 private_metadata)) {
561 goto err;
562 }
563
564 if (CBS_len(&in) != 0) {
565 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
566 goto err;
567 }
568
569 if (!CBB_finish(&response, out, out_len)) {
570 goto err;
571 }
572
573 *out_tokens_issued = num_to_issue;
574 ret = 1;
575
576 err:
577 CBB_cleanup(&response);
578 return ret;
579 }
580
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)581 static int trust_token_issuer_redeem_impl(
582 const TRUST_TOKEN_ISSUER *ctx, uint32_t *out_public, uint8_t *out_private,
583 TRUST_TOKEN **out_token, uint8_t **out_client_data,
584 size_t *out_client_data_len, const uint8_t *request, size_t request_len,
585 int include_message, const uint8_t *msg, size_t msg_len) {
586 CBS request_cbs, token_cbs;
587 CBS_init(&request_cbs, request, request_len);
588 if (!CBS_get_u16_length_prefixed(&request_cbs, &token_cbs)) {
589 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR);
590 return 0;
591 }
592
593 uint32_t public_metadata = 0;
594 uint8_t private_metadata = 0;
595
596 // Parse the token. If there is an error, treat it as an invalid token.
597 if (!CBS_get_u32(&token_cbs, &public_metadata)) {
598 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN);
599 return 0;
600 }
601
602 const struct trust_token_issuer_key_st *key =
603 trust_token_issuer_get_key(ctx, public_metadata);
604 uint8_t nonce[TRUST_TOKEN_NONCE_SIZE];
605 if (key == NULL ||
606 !ctx->method->read(&key->key, nonce, &private_metadata,
607 CBS_data(&token_cbs), CBS_len(&token_cbs),
608 include_message, msg, msg_len)) {
609 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN);
610 return 0;
611 }
612
613 CBS client_data;
614 if (!CBS_get_u16_length_prefixed(&request_cbs, &client_data) ||
615 (ctx->method->has_srr && !CBS_skip(&request_cbs, 8)) ||
616 CBS_len(&request_cbs) != 0) {
617 OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR);
618 return 0;
619 }
620
621 uint8_t *client_data_buf = NULL;
622 size_t client_data_len = 0;
623 if (!CBS_stow(&client_data, &client_data_buf, &client_data_len)) {
624 goto err;
625 }
626
627 TRUST_TOKEN *token = TRUST_TOKEN_new(nonce, TRUST_TOKEN_NONCE_SIZE);
628 if (token == NULL) {
629 goto err;
630 }
631 *out_public = public_metadata;
632 *out_private = private_metadata;
633 *out_token = token;
634 *out_client_data = client_data_buf;
635 *out_client_data_len = client_data_len;
636
637 return 1;
638
639 err:
640 OPENSSL_free(client_data_buf);
641 return 0;
642 }
643
644
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)645 int TRUST_TOKEN_ISSUER_redeem(const TRUST_TOKEN_ISSUER *ctx,
646 uint32_t *out_public, uint8_t *out_private,
647 TRUST_TOKEN **out_token,
648 uint8_t **out_client_data,
649 size_t *out_client_data_len,
650 const uint8_t *request, size_t request_len) {
651 return trust_token_issuer_redeem_impl(ctx, out_public, out_private, out_token,
652 out_client_data, out_client_data_len,
653 request, request_len, 0, NULL, 0);
654 }
655
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)656 int TRUST_TOKEN_ISSUER_redeem_over_message(
657 const TRUST_TOKEN_ISSUER *ctx, uint32_t *out_public, uint8_t *out_private,
658 TRUST_TOKEN **out_token, uint8_t **out_client_data,
659 size_t *out_client_data_len, const uint8_t *request, size_t request_len,
660 const uint8_t *msg, size_t msg_len) {
661 return trust_token_issuer_redeem_impl(ctx, out_public, out_private, out_token,
662 out_client_data, out_client_data_len,
663 request, request_len, 1, msg, msg_len);
664 }
665
get_metadata_obfuscator(const uint8_t * key,size_t key_len,const uint8_t * client_data,size_t client_data_len)666 static uint8_t get_metadata_obfuscator(const uint8_t *key, size_t key_len,
667 const uint8_t *client_data,
668 size_t client_data_len) {
669 uint8_t metadata_obfuscator[SHA256_DIGEST_LENGTH];
670 SHA256_CTX sha_ctx;
671 SHA256_Init(&sha_ctx);
672 SHA256_Update(&sha_ctx, key, key_len);
673 SHA256_Update(&sha_ctx, client_data, client_data_len);
674 SHA256_Final(metadata_obfuscator, &sha_ctx);
675 return metadata_obfuscator[0] >> 7;
676 }
677
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)678 int TRUST_TOKEN_decode_private_metadata(const TRUST_TOKEN_METHOD *method,
679 uint8_t *out_value, const uint8_t *key,
680 size_t key_len, const uint8_t *nonce,
681 size_t nonce_len,
682 uint8_t encrypted_bit) {
683 uint8_t metadata_obfuscator =
684 get_metadata_obfuscator(key, key_len, nonce, nonce_len);
685 *out_value = encrypted_bit ^ metadata_obfuscator;
686 return 1;
687 }
688